题目:http://poj.org/problem?id=3026
题意真的很难懂。。。
题目大意:一个迷宫,'#'是墙,不可行走,‘ ‘是可行走的,现在题目是要求从s出发把所有的字母(‘A’)连起来的最短路径
各个字母的边权用bfs可求:墙不可走,超出矩阵范围不可走,建立任意字母之间最短距离的图
最后用prim就可以了
注:用getchar会wa,不知道为什么。。。
View Code
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define inf 3000 5 using namespace std; 6 char map[105][105];//存储原始的迷宫 7 int no[105][105];//记录字母的下标,map[i][j]是否为字母 8 struct node 9 { 10 int x,y; 11 int num; 12 }que[2510]; 13 int nonde[4][2]={{0,-1},{0,1},{1,0},{-1,0}};//移动的方向 14 int cmap[105][105];//存储各个字母之间的最短距离 15 int n,m; 16 int nnum;//字母的总数 17 void bfs(int i,int j) 18 { 19 int vis[105][105]; 20 int head,tail; 21 memset(vis,0,sizeof(vis)); 22 head=tail=0; 23 que[head].x=i; 24 que[head].y=j; 25 que[head].num=0; 26 vis[i][j]=1; 27 tail++; 28 while(head<tail) 29 { 30 if(no[que[head].x][que[head].y]) 31 { 32 cmap[no[i][j]][no[que[head].x][que[head].y]]=que[head].num;//将此时的字母间的最短路径放入cmap 33 } 34 for(int k=0;k<4;k++) 35 { 36 int kx=que[head].x+nonde[k][0]; 37 int ky=que[head].y+nonde[k][1]; 38 if(kx>=1&&kx<=m&&ky>=1&&ky<=n) 39 { 40 if(!vis[kx][ky]&&map[kx][ky-1]!='#') 41 { 42 que[tail].x=kx; 43 que[tail].y=ky; 44 que[tail].num=que[head].num+1; 45 vis[kx][ky]=1; 46 tail++; 47 } 48 } 49 } 50 head++; 51 } 52 return ; 53 } 54 void prim() 55 { 56 int dis[105]; 57 int viss[105]; 58 int i,j; 59 memset(viss,0,sizeof(viss)); 60 for(i=1;i<=nnum;i++) 61 { 62 dis[i]=cmap[1][i]; 63 } 64 viss[1]=1; 65 int min,pos; 66 int ans=0; 67 for(i=1;i<=nnum;i++) 68 { 69 min=inf; 70 for(j=2;j<=nnum;j++) 71 { 72 if(!viss[j]&&min>dis[j]) 73 { 74 pos=j; 75 min=dis[j]; 76 } 77 } 78 if(min==inf) 79 break; 80 viss[pos]=1; 81 ans+=min; 82 for(j=2;j<=nnum;j++) 83 { 84 if(!viss[j]&&dis[j]>cmap[pos][j]) 85 dis[j]=cmap[pos][j]; 86 } 87 } 88 printf("%d\n",ans); 89 } 90 int main() 91 { 92 int t,i,j; 93 scanf("%d",&t); 94 while(t--) 95 { 96 scanf("%d%d",&n,&m); 97 char temp[51]; 98 gets(temp);//用getchar()会wa 99 memset(no,0,sizeof(no)); 100 nnum=0; 101 for(i=1;i<=m;i++) 102 { 103 gets(map[i]); 104 for(j=0;j<n;j++) 105 { 106 if(map[i][j]=='A'||map[i][j]=='S') 107 { 108 nnum++; 109 no[i][j+1]=nnum; 110 } 111 } 112 } 113 for(i=1;i<=m;i++) 114 { 115 for(j=1;j<=n;j++) 116 { 117 if(no[i][j]) 118 bfs(i,j);//[i][j]到其他点的边权 119 } 120 } 121 prim(); 122 } 123 124 return 0; 125 }