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)

思路:老鼠必须从硬度小的开始吃,这样才能有体力去吃其他硬度大的奶酪。这样就是求老鼠分别到各个点的最短路即可。

  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 }
View Code

 

posted @ 2015-03-28 18:30  NowAndForever  阅读(393)  评论(0编辑  收藏  举报