poj 4105 拯救公主(bfs)

原题网址:http://bailian.openjudge.cn/practice/4105/

思路:

    每个位置包括的状态:所在的位置,获得的宝石。

    广搜:用队列存储达到某个位置时,获得的宝石完全相同的最少用时。

    传送门另外考虑即可。

详细代码:

 

 1 #include <cstdio>
 2 #include <queue>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 const int INF = 0x44444444;
 7 int gater[10], gatec[10], cnt, n,m, k, dp[210][210][1<<5],// 存储传送门的数量,到大某个位置时,获得宝石完全相同时的最少用时
 8     ex,ey;
 9 char mp[210][210];
10 queue<int> que;
11 
12 int main(){
13     freopen("C:\\Users\\yyf\\Documents\\CppFiles\\in.txt", "r", stdin);
14     int t,dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
15     scanf("%d", &t);
16     while(t--){
17         cnt=0;
18         memset(dp, 0x44, sizeof(dp));
19         scanf("%d%d%d", &n, &m, &k);
20         for(int i=0; i<n; ++i){
21             scanf("%s", mp[i]);
22             for(int j=0; j<m; ++j){
23                 switch(mp[i][j]){
24                     case '$':     gater[cnt]=i;gatec[cnt++]=j;
25                                 break;
26                     case 'S':     que.push(i), que.push(j), que.push(0);
27                                   dp[i][j][0]=0;
28                                   break;
29                     case 'E':     ex=i, ey=j; break;
30                     default :     break;
31                 }
32             }
33         }
34         while(!que.empty()){
35             int tr = que.front(); que.pop();
36             int tc = que.front(); que.pop();
37             int ts = que.front(); que.pop();
38             for(int i=0; i<4; ++i){// 四个方向
39                 int r=tr+dx[i], c=tc+dy[i];
40                 if(r<0 || c<0 || r==n || c==m || mp[r][c]=='#') continue;
41                 int t = dp[tr][tc][ts]+1, s=ts;
42                 if('0'<=mp[r][c] && mp[r][c]<='4'){
43                     s |= 1<<mp[r][c]-'0';
44                 }
45                 if(t>=dp[r][c][s]) continue;// 剪枝
46                 if(mp[r][c]=='$'){
47                     for(int j=0; j<cnt; ++j){
48                         dp[gater[j]][gatec[j]][s] = t;
49                         que.push(gater[j]), que.push(gatec[j]);
50                         que.push(s);
51                     }
52                 }
53                 else {
54                     dp[r][c][s]=t;
55                     if(mp[r][c]=='E' && s==(1<<k)-1) continue;
56                     que.push(r), que.push(c), que.push(s);
57                 }
58             }
59         }
60         if(dp[ex][ey][(1<<k)-1] == INF) printf("oop!\n");
61         else printf("%d\n", dp[ex][ey][(1<<k)-1]);
62     }
63     return 0;
64 }

 

posted @ 2016-08-17 22:42  Keep_Going  阅读(992)  评论(0编辑  收藏  举报