POJ 3026 Borg Maze(Prim+bfs求各點間距離)
阿新 • • 發佈:2017-11-27
spa () 去掉 ets size har href http int
題目鏈接:http://poj.org/problem?id=3026
題目大意:在一個y行 x列的迷宮中,有可行走的通路空格’ ‘,不可行走的墻’#’,還有兩種英文字母A和S,現在從S出發,要求用最短的路徑L連接所有字母,輸出這條路徑L的總長度。
解題思路:相當於所有的字母A和S都是結點,求連接這些結點的最小距離和,是最小生成樹的題目。先用BFS求各點間的距離,然後再用Prim(Kruskal也可以)求出最小距離就可以了。
註意:輸完行列m和n之後,後面有一堆空格,要用gets()去掉,題目有問題,超級坑。
代碼:
1 #include<iostream> 2#include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<algorithm> 6 using namespace std; 7 const int N=1e2+5; 8 const int MAXN=1e2+5; 9 const int INF=0x3f3f3f3f; 10 11 int n,m; 12 int d[4][2]={0,1,0,-1,-1,0,1,0}; 13 int num[N][N],cost[N][N],root[MAXN],low[MAXN];14 bool vis[N][N],used[MAXN]; 15 char str[N][N]; 16 17 struct node{ 18 int x,y,step; 19 node(){} 20 node(int x,int y,int step){ 21 this->x=x; 22 this->y=y; 23 this->step=step; 24 } 25 }pre; 26 27 //(x,y)點到各個點之間的最短距離 28 voidbfs(int x,int y){ 29 memset(vis,false,sizeof(vis)); 30 queue<node>q; 31 q.push(node(x,y,0)); 32 vis[x][y]=true; 33 while(!q.empty()){ 34 pre=q.front(); 35 q.pop(); 36 for(int i=0;i<4;i++){ 37 int xx=pre.x+d[i][0]; 38 int yy=pre.y+d[i][1]; 39 int t=pre.step+1; 40 if(x<=0||y<=0||x>n||y>m||vis[xx][yy]||str[xx][yy]==‘#‘) 41 continue; 42 if(str[xx][yy]==‘S‘||str[xx][yy]==‘A‘) 43 cost[num[x][y]][num[xx][yy]]=t; 44 vis[xx][yy]=true; 45 q.push(node(xx,yy,t)); 46 } 47 } 48 } 49 //Prim求最小生成樹 50 int Prim(int cnt){ 51 memset(used,false,sizeof(used)); 52 for(int i=1;i<=cnt;i++){ 53 low[i]=cost[1][i]; 54 } 55 used[1]=true; 56 int ans=0; 57 for(int i=1;i<cnt;i++){ 58 int k=-1; 59 for(int j=1;j<=cnt;j++){ 60 if(!used[j]&&(k==-1||low[k]>low[j])){ 61 k=j; 62 } 63 } 64 if(k==-1||low[k]==INF) return -1; 65 ans+=low[k]; 66 used[k]=true; 67 for(int j=1;j<=cnt;j++){ 68 if(!used[j]&&low[j]>cost[k][j]) 69 low[j]=cost[k][j]; 70 } 71 } 72 return ans; 73 } 74 75 int main(){ 76 int t; 77 char tmp[105]; 78 scanf("%d",&t); 79 while(t--){ 80 memset(cost,0x3f,sizeof(cost)); 81 scanf("%d%d",&m,&n); 82 //註意行列後面有一大堆空格要用gets(),出題人怕是個智。。。 83 gets(tmp); 84 int cnt=0; 85 for(int i=1;i<=n;i++){ 86 gets(str[i]+1); 87 for(int j=1;j<=m;j++){ 88 if(str[i][j]==‘S‘||str[i][j]==‘A‘) 89 num[i][j]=++cnt; 90 } 91 } 92 for(int i=1;i<=n;i++){ 93 for(int j=1;j<=m;j++){ 94 if(str[i][j]==‘S‘||str[i][j]==‘A‘){ 95 bfs(i,j); 96 } 97 } 98 } 99 printf("%d\n",Prim(cnt)); 100 } 101 return 0; 102 }
POJ 3026 Borg Maze(Prim+bfs求各點間距離)