Aizu - 0558 Cheese (bfs)
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=49879
在H * W的地图上有N个奶酪工厂,分别生产硬度为1-N的奶酪。有一只吃货老鼠准备从老鼠洞出发吃遍每一个工厂的奶酪。老鼠有一个体力值,初始时为1,每吃一个工厂的奶酪体力值增加1(每个工厂只能吃一次),且老鼠只能吃硬度不大于当前体力值的奶酪。
老鼠从当前格走到相邻的无障碍物的格(上下左右)需要时间1单位,有障碍物的格不能走。走到工厂上时即可吃到该工厂的奶酪,吃奶酪时间不计。问吃遍所有奶酪最少用时。
输入:第一行三个整数H(1 <= H <= 1000)、W(1 <= W <=1000)、N(1 <= N <= 9),之后H行W列为地图, “.“为空地, ”X“为障碍物,”S“为老鼠洞, 1-N代表硬度为1-N的奶酪的工厂。(中文翻译参考了http://bbs.byr.cn/#!article/ACM_ICPC/73337?au=Milrivel)
思路:老鼠必须从硬度小的开始吃,这样才能有体力去吃其他硬度大的奶酪。这样就是求老鼠分别到各个点的最短路即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 //#include <cmath> 4 #include <vector> 5 #include <cstring> 6 #include <string> 7 #include <algorithm> 8 #include <string> 9 #include <set> 10 #include <functional> 11 #include <numeric> 12 #include <sstream> 13 #include <stack> 14 #include <map> 15 #include <queue> 16 17 #define CL(arr, val) memset(arr, val, sizeof(arr)) 18 19 #define ll long long 20 #define inf 0x7f7f7f7f 21 #define lc l,m,rt<<1 22 #define rc m + 1,r,rt<<1|1 23 #define pi acos(-1.0) 24 25 #define L(x) (x) << 1 26 #define R(x) (x) << 1 | 1 27 #define MID(l, r) (l + r) >> 1 28 #define Min(x, y) (x) < (y) ? (x) : (y) 29 #define Max(x, y) (x) < (y) ? (y) : (x) 30 #define E(x) (1 << (x)) 31 #define iabs(x) (x) < 0 ? -(x) : (x) 32 #define OUT(x) printf("%I64d\n", x) 33 #define lowbit(x) (x)&(-x) 34 #define Read() freopen("a.txt", "r", stdin) 35 #define Write() freopen("dout.txt", "w", stdout); 36 #define maxn 1000000000 37 #define N 1010 38 using namespace std; 39 40 int h,w,x; 41 int dir[4][2]={-1,0,0,1,0,-1,1,0}; 42 typedef pair<int,int> P; //pair表示状态 43 char maze[N][N]; 44 int d[N][N]; 45 P p; 46 47 int bfs(char c) 48 { 49 queue<P>que; 50 for(int i=0;i<h;i++) //首先把距离初始为无穷大,然后不断更新最小值 51 for(int j=0;j<w;j++) d[i][j]=maxn; 52 que.push(p); 53 d[p.first][p.second]=0; //起点的距离为0 54 P p1,p2; 55 while(que.size()) 56 { 57 p1=que.front(); que.pop(); 58 if(maze[p1.first][p1.second]==c) 59 { 60 p=p1; break; //找到终点 61 } 62 for(int i=0;i<4;i++) 63 { 64 p2.first=p1.first+dir[i][0]; 65 p2.second=p1.second+dir[i][1]; 66 if(p2.first>=0&&p2.first<h&&p2.second>=0&&p2.second<w&&maze[p2.first][p2.second]!='X'&&d[p2.first][p2.second]==maxn) 67 { //判断是否可以移动以及是否访问过 d[i][j]!=maxn即访问过 68 que.push(p2); 69 d[p2.first][p2.second]=d[p1.first][p1.second]+1; 70 } 71 } 72 } 73 return d[p.first][p.second]; 74 } 75 76 int main() 77 { 78 //freopen("a.txt","r",stdin); 79 while(~scanf("%d%d%d",&h,&w,&x)) 80 { 81 getchar(); 82 int sum=0; 83 for(int i=0;i<h;i++) 84 { 85 scanf("%s",maze[i]); 86 //printf("%s\n",maze[i]); 87 for(int j=0;j<w;j++) 88 { 89 if(maze[i][j]=='S') 90 { 91 p.first=i; 92 p.second=j; 93 } 94 } 95 } 96 //printf("%d %d\n",p1.first,p1.second); 97 for(int i=1;i<=x;i++) //x个点,x个bfs 98 { 99 sum+=bfs('0'+i); 100 } 101 printf("%d\n",sum); 102 } 103 return 0; 104 }