• 紫书搜索 例题7-9 UVA


    题目链接:

    https://vjudge.net/problem/UVA-1601

    题意:

    题解:

    http://blog.csdn.net/qq_29169749/article/details/51420097
    隐式图搜索问题,类似dijkstra,用bfs解决,这个是单向搜索,弊端是有时候随着搜索的深入,可扩展的结点会越来越多,造成效率变慢,用双向bfs可以解决这个问题

    代码:

    双向bfs:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 #define MS(a) memset(a,0,sizeof(a))
      5 #define MP make_pair
      6 #define PB push_back
      7 const int INF = 0x3f3f3f3f;
      8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
      9 inline ll read(){
     10     ll x=0,f=1;char ch=getchar();
     11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     13     return x*f;
     14 }
     15 //////////////////////////////////////////////////////////////////////////
     16 const int maxn = 1e5+10;
     17 
     18 int w, h, n, s[3], t[3];
     19 char dataset[20][20];
     20 int G[200][5], color[200][200][200], dis[200][200][200];
     21 int deg[200];
     22 
     23 int dx[] = {0,0,0,1,-1};
     24 int dy[] = {0,1,-1,0,0};
     25 
     26 int ID(int a,int b,int c){
     27     return (a<<16) | (b<<8) | c;
     28 }
     29 
     30 bool conflict(int a,int b,int a2,int b2){
     31     return a2==b2 || (a==b2 && b==a2);
     32 }
     33 
     34 int bfs(){
     35     queue<int> qf;
     36     queue<int> qb;
     37     dis[s[0]][s[1]][s[2]] = 0;
     38     dis[t[0]][t[1]][t[2]] = 1;
     39     qf.push(ID(s[0],s[1],s[2]));
     40     qb.push(ID(t[0],t[1],t[2]));
     41     color[s[0]][s[1]][s[2]] = 1;
     42     color[t[0]][t[1]][t[2]] = 2;
     43 
     44     while(!qf.empty() || !qb.empty()){
     45         int fnum = qf.size(), bnum = qb.size();  //一层一层的拓展。而不是一个点
     46         while(fnum--){ 
     47             int u = qf.front(); qf.pop();
     48             int a = (u>>16)&0xff, b = (u>>8)&0xff, c = u&0xff; //解码出出列状态三个小鬼的位置
     49 
     50             for(int i=0; i<deg[a]; i++){
     51                 int a2 = G[a][i];
     52                 for(int j=0; j<deg[b]; j++){
     53                     int b2 = G[b][j];
     54                     if(conflict(a,b,a2,b2)) continue;
     55                     for(int k=0; k<deg[c]; k++){
     56                         int c2 = G[c][k];
     57                         if(conflict(a,c,a2,c2)) continue;
     58                         if(conflict(b,c,b2,c2)) continue;
     59 
     60                         // if(dis[a2][b2][c2] != -1) continue;  // 不能再这样判断是否访问过了,因为是双向
     61                         if(color[a2][b2][c2] == 0){
     62                             color[a2][b2][c2] = 1;
     63                             dis[a2][b2][c2] = dis[a][b][c]+1;
     64                             qf.push(ID(a2,b2,c2));
     65                         }else if(color[a2][b2][c2] == 2){
     66                             return dis[a][b][c] + dis[a2][b2][c2];  // 这就是为啥最开始的终点初始为1步;
     67                         }
     68                     }
     69                 }
     70             }
     71         }
     72 
     73         while(bnum--){
     74             int u = qb.front(); qb.pop();
     75             int a = (u>>16)&0xff, b = (u>>8)&0xff, c = u&0xff;
     76 
     77             for(int i=0; i<deg[a]; i++){
     78                 int a2 = G[a][i];
     79                 for(int j=0; j<deg[b]; j++){
     80                     int b2 = G[b][j];
     81                     if(conflict(a,b,a2,b2)) continue;
     82                     for(int k=0; k<deg[c]; k++){
     83                         int c2 = G[c][k];
     84                         if(conflict(a,c,a2,c2)) continue;
     85                         if(conflict(b,c,b2,c2)) continue;
     86 
     87                         // if(dis[a2][b2][c2] != -1) continue; 
     88                         if(color[a2][b2][c2] == 0){
     89                             color[a2][b2][c2] = 2;
     90                             dis[a2][b2][c2] = dis[a][b][c] + 1;
     91                             qb.push(ID(a2,b2,c2));
     92                         }else if(color[a2][b2][c2] == 1){
     93                             return dis[a][b][c] + dis[a2][b2][c2];
     94                         }
     95                     }
     96                 }
     97             }
     98         }
     99     }
    100 
    101     return -1;
    102 }
    103 
    104 int main(){
    105     while(scanf("%d%d%d
    ",&w,&h,&n)==3 && (w+h+n)){
    106         for(int i=0; i<h; i++) gets(dataset[i]);
    107         int cnt=0,x[200],y[200],id[20][20];
    108         for(int i=0; i<h; i++)
    109             for(int j=0; j<w; j++){
    110                 if(dataset[i][j]!='#'){
    111                     x[cnt]=i,y[cnt]=j,id[i][j] = cnt;  // cnt表示有多少个空白块
    112                     if(islower(dataset[i][j])) s[dataset[i][j]-'a'] = cnt;
    113                     if(isupper(dataset[i][j])) t[dataset[i][j]-'A'] = cnt; 
    114                     cnt++;
    115                 }
    116             }
    117 
    118         for(int i=0; i<cnt; i++){ // 用空白块建图
    119             deg[i] = 0;  // i这个白块周围有多少的白块,就是连线嘛
    120             for(int j=0; j<5; j++){
    121                 int tx=x[i]+dx[j], ty=y[i]+dy[j];
    122                 if(dataset[tx][ty] != '#') G[i][deg[i]++] = id[tx][ty];
    123             }
    124         }
    125 
    126         if(n <= 2) { deg[cnt]=1; G[cnt][0]=cnt; s[2]=t[2]=cnt; cnt++;}
    127         if(n <= 1) { deg[cnt]=1; G[cnt][0]=cnt; s[1]=t[1]=cnt; cnt++;}
    128 
    129         memset(dis,-1,sizeof(dis));
    130         memset(color,0,sizeof(color));
    131 
    132         printf("%d
    ",bfs());
    133 
    134     }
    135 
    136     return 0;
    137 }

    单向bfs:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 #define MS(a) memset(a,0,sizeof(a))
      5 #define MP make_pair
      6 #define PB push_back
      7 const int INF = 0x3f3f3f3f;
      8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
      9 inline ll read(){
     10     ll x=0,f=1;char ch=getchar();
     11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     13     return x*f;
     14 }
     15 //////////////////////////////////////////////////////////////////////////
     16 const int maxn = 1e5+10;
     17 
     18 int w,h,n;
     19 int G[200][5],dis[200][200][200],deg[200],s[3],t[3];
     20 char dataset[20][20];
     21 int dx[] = {0,0,0,1,-1};
     22 int dy[] = {0,1,-1,0,0};
     23 
     24 inline int ID(int a,int b,int c){
     25     return (a<<16) | (b<<8) | c;
     26 }
     27 
     28 bool conflict(int a,int b,int a2,int b2){
     29     return (a2==b2) || (a==b2 && b==a2);
     30 }
     31 
     32 int bfs(){
     33     queue<int> q;
     34     q.push(ID(s[0],s[1],s[2]));
     35     dis[s[0]][s[1]][s[2]] = 0;
     36     while(!q.empty()){
     37         int u = q.front(); q.pop();
     38         int a = (u>>16)&0xff, b = (u>>8)&0xff, c = u & 0xff;
     39         if(a==t[0] && b==t[1] && c==t[2]) return dis[a][b][c];
     40 
     41         for(int i=0; i<deg[a]; i++){
     42             int a2 = G[a][i];
     43             for(int j=0; j<deg[b]; j++){
     44                 int b2 = G[b][j];
     45                 if(conflict(a,b,a2,b2)) continue;
     46                 for(int k=0; k<deg[c]; k++){
     47                     int c2 = G[c][k];
     48                     if(conflict(a,c,a2,c2)) continue;
     49                     if(conflict(b,c,b2,c2)) continue;
     50 
     51                     if(dis[a2][b2][c2]!=-1) continue;
     52                     dis[a2][b2][c2] = dis[a][b][c] + 1;
     53                     q.push(ID(a2,b2,c2)); 
     54                 }
     55             }
     56         }
     57     }
     58     return -1;
     59 }
     60 
     61 int main(){
     62     while(~scanf("%d%d%d
    ",&w,&h,&n) && n){
     63         for(int i=0; i<h; i++) gets(dataset[i]);
     64 
     65         // for(int i = 0; i < h; i++)  fgets(dataset[i], 20, stdin);
     66 
     67         int cnt=0,x[200],y[200],id[20][20];
     68         for(int i=0; i<h; i++)
     69             for(int j=0; j<w; j++){
     70                 if(dataset[i][j] != '#'){
     71                     x[cnt]=i,y[cnt]=j,id[i][j]=cnt;
     72                     if(islower(dataset[i][j])) s[dataset[i][j]-'a'] = cnt;
     73                     else if(isupper(dataset[i][j])) t[dataset[i][j]-'A'] = cnt;
     74                     cnt++;
     75                 }
     76             }
     77 
     78         for(int i=0; i<cnt; i++){
     79             deg[i] = 0;
     80             for(int j=0; j<5; j++){
     81                 int tx=x[i]+dx[j], ty=y[i]+dy[j];
     82                 if(dataset[tx][ty]!='#') G[i][deg[i]++] = id[tx][ty];
     83             }
     84         }
     85         if(n<=2) { deg[cnt]=1; G[cnt][0]=cnt; s[2]=t[2]=cnt; cnt++;}
     86         if(n<=1) { deg[cnt]=1; G[cnt][0]=cnt; s[1]=t[1]=cnt; cnt++;}
     87 
     88         memset(dis,-1,sizeof(dis));
     89 
     90         printf("%d
    ",bfs());
     91     }
     92 
     93     return 0;
     94 }
     95 5 5 2
     96 #####
     97 #A#B#
     98 #   #
     99 #b#a#
    100 #####
    101 16 4 3
    102 ################
    103 ## ########## ##
    104 #    ABCcba    #
    105 ################
    106 0 0 0
  • 相关阅读:
    DateTimePicker常用格式类型
    自定义TreeNode
    memoのPython环境配置
    关于隐式积分方程的一些问题
    Position Based Dynamics【译】
    memoのMac折腾记录
    20210425 助教一周小结(第十二周)
    20210328 助教一周小结(第八周)
    20210307 助教一周小结(第五周)
    20210404 助教一周小结(第九周)
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6827607.html
Copyright © 2020-2023  润新知