1. 程式人生 > >CCF 201409-4 最優配餐

CCF 201409-4 最優配餐

解決 標記 內存 多個 tab 連鎖 bfs == find

試題編號: 201409-4
試題名稱: 最優配餐
時間限制: 1.0s
內存限制: 256.0MB
問題描述: 問題描述   棟棟最近開了一家餐飲連鎖店,提供外賣服務。隨著連鎖店越來越多,怎麽合理的給客戶送餐成為了一個急需解決的問題。
  棟棟的連鎖店所在的區域可以看成是一個n×n的方格圖(如下圖所示),方格的格點上的位置上可能包含棟棟的分店(綠色標註)或者客戶(藍色標註),有一些格點是不能經過的(紅色標註)。
  方格圖中的線表示可以行走的道路,相鄰兩個格點的距離為1。棟棟要送餐必須走可以行走的道路,而且不能經過紅色標註的點。

技術分享
  送餐的主要成本體現在路上所花的時間,每一份餐每走一個單位的距離需要花費1塊錢。每個客戶的需求都可以由棟棟的任意分店配送,每個分店沒有配送總量的限制。
  現在你得到了棟棟的客戶的需求,請問在最優的送餐方式下,送這些餐需要花費多大的成本。 輸入格式   輸入的第一行包含四個整數n, m, k, d,分別表示方格圖的大小、棟棟的分店數量、客戶的數量,以及不能經過的點的數量。
  接下來m行,每行兩個整數xi, yi,表示棟棟的一個分店在方格圖中的橫坐標和縱坐標。
  接下來k行,每行三個整數xi, yi, ci,分別表示每個客戶在方格圖中的橫坐標、縱坐標和訂餐的量。(註意,可能有多個客戶在方格圖中的同一個位置)
  接下來d行,每行兩個整數,分別表示每個不能經過的點的橫坐標和縱坐標。 輸出格式   輸出一個整數,表示最優送餐方式下所需要花費的成本。 樣例輸入 10 2 3 3
1 1
8 8
1 5 1
2 3 3
6 7 2
1 2
2 2
6 8 樣例輸出 29 評測用例規模與約定   前30%的評測用例滿足:1<=n <=20。
  前60%的評測用例滿足:1<=n<=100。
  所有評測用例都滿足:1<=n<=1000,1<=m, k, d<=n^2。可能有多個客戶在同一個格點上。每個客戶的訂餐量不超過1000,每個客戶所需要的餐都能被送到。

關鍵詞:自定義的map的key類型(重載less運算),bfs,queue,方向判斷控制dir,取值範圍溢出

  1 #include<iostream>
  2 #include<vector>
  3 #include<queue>
  4 #include<map>
  5 using namespace std;
  6 struct YPoint{
  7     int x;//客戶
  8     int y;//客戶
  9     int step;//分店:步數 客戶:單價
 10 };
 11 bool operator
< (const YPoint &p1,const YPoint &p2) { 12 if(p1.x<p2.x 13 || 14 p1.x == p2.x 15 && 16 p1.y<p2.y 17 ){ 18 return true; 19 } 20 else{ 21 return false; 22 } 23 } 24 int n; 25 int m; 26 int
k; 27 int d; 28 int dir[4][2] = { 29 {-1,0}, 30 {0,1}, 31 {1,0}, 32 {0,-1}, 33 }; 34 map<YPoint,long long> ke;//step單價 int總價 35 int findnum = 0; 36 bool bfs(vector<vector<char> > &v,queue<YPoint> &q); 37 int main(){ 38 //freopen("in2.txt","r",stdin); 39 cin >> n >> m >> k >> d; 40 vector<vector<char> > v;//地圖標記 0未走 1已走、分店 2客戶 // 3分店 41 vector<char> vr; 42 for(int i = 0;i<n;i++){ 43 vr.clear(); 44 for(int j = 0;j<n;j++){ 45 vr.push_back(0); 46 } 47 v.push_back(vr); 48 } 49 //分店 50 queue<YPoint> q; // 步數 51 for(int i = 0;i<m;i++){ 52 int bufx,bufy; 53 cin >> bufx >> bufy; 54 YPoint bp; 55 bp.x = bufx-1; 56 bp.y = bufy-1; 57 bp.step = 0; 58 v[bufy-1][bufx-1] = 1; 59 q.push(bp); 60 } 61 //客戶 62 for(int i = 0;i<k;i++){ 63 int bufx,bufy,bufv; 64 cin >> bufx >> bufy >> bufv; 65 YPoint bp; 66 bp.x = bufx-1; 67 bp.y = bufy-1; 68 bp.step = bufv; 69 if(ke.count(bp)){ 70 bp.step += ke.find(bp)->first.step; 71 ke.erase(ke.find(bp)); 72 } 73 ke[bp] = -1; 74 v[bp.y][bp.x] = 2; 75 } 76 //禁止 77 for(int i = 0;i<d;i++){ 78 int bufx,bufy; 79 cin >> bufx >> bufy; 80 v[bufy-1][bufx-1] = 1; 81 } 82 while(!q.empty()){ 83 if(bfs(v,q)){ 84 break; 85 } 86 } 87 long long sum = 0; 88 for(map<YPoint,long long>::iterator it = ke.begin();it != ke.end();it++){ 89 sum+=it->second; 90 } 91 cout << sum; 92 return 0; 93 } 94 bool bfs(vector<vector<char> > &v,queue<YPoint> &q){ 95 YPoint buf; 96 YPoint head = q.front(); 97 q.pop(); 98 for(int i = 0;i<4;i++){ 99 int xx = head.x+dir[i][0]; 100 int yy = head.y+dir[i][1]; 101 if(xx >= 0 102 && 103 xx < n 104 && 105 yy >= 0 106 && 107 yy < n 108 && 109 v[yy][xx] != 1){ 110 buf.x = xx; 111 buf.y = yy; 112 buf.step = head.step+1; 113 if(v[buf.y][buf.x] == 2){ 114 map<YPoint,long long>::iterator kit = ke.find(buf); 115 kit->second = kit->first.step*buf.step; 116 findnum++; 117 if(findnum >= k){ 118 return true; 119 } 120 } 121 v[buf.y][buf.x] = 1; 122 q.push(buf); 123 } 124 } 125 return false; 126 }

CCF 201409-4 最優配餐