Borg Maze POJ - 3026

 

题目链接:https://vjudge.net/problem/POJ-3026

题意:题目讲的其实有点迷糊。。。总的来说就是,在一个地图上,你需要把所有的‘A’和‘S’连接起来,使得所有线段累加长度最短,那么很显然,这里需要最小生成树。

思路:地图上分布着‘A’和‘S’,我们需要把图上的信息提取出一个图,G(V,E)。那么我们就可以用prime算法了。

开始,我们可以先把‘A’和‘S’编号,然后用bfs跑地图,枚举每个‘A’和‘S’其他的‘A’和‘S’的距离,先生成一个距离矩阵,生成了矩阵之后,就可以套prime板子了。

建图是关键,代码中会有些解释


  1 #include <iostream>
  2 #include <cstring>
  3 #include<vector>
  4 #include<string>
  5 #include <cmath>
  6 #include <map>
  7 #include <queue>
  8 #include <algorithm>
  9 #include <cstdio>
 10 using namespace std;
 11 
 12 #define inf 99999
 13 #define rep(i,j,k) for(int i = (j); i <= (k); i++)
 14 #define rep__(i,j,k) for(int i = (j); i < (k); i++)
 15 #define per(i,j,k) for(int i = (j); i >= (k); i--)
 16 #define per__(i,j,k) for(int i = (j); i > (k); i--)
 17 
 18 
 19 const int N = 110;
 20 int mv_x[] = {0,0,1,-1};
 21 int mv_y[] = {1,-1,0,0};
 22 int G[N][N]; //路线
 23 string mp[N]; //原始地图
 24 int num[N][N];//编号图
 25 bool vis[N][N];//bfs
 26 int sx,sy;//S
 27 int n,m;
 28 int cnt;//编号
 29 
 30 struct node{
 31 
 32     int x,y,v;
 33 };
 34 
 35 
 36 void init_G(){
 37 
 38     rep(i,1,cnt){
 39         rep(j,1,cnt){
 40             if(i == j) G[i][j] = 0;
 41             else G[i][j] = inf;
 42         }
 43     }
 44 }
 45 
 46 void set_num(){
 47     
 48     cnt = 0;
 49     rep__(i,0,n){
 50         rep__(j,0,m){
 51             if(mp[i][j] == 'A' || mp[i][j] == 'S') num[i][j] = ++cnt; //把‘A’和‘S’编号
 52         }
 53     }
 54 }
 55 
 56 inline bool check(int x,int y){
 57     return x >= 0 && x < n && y >= 0 && y < m;
 58 }
 59 
 60 void bfs(int now_x,int now_y){
 61 
 62     memset(vis,0,sizeof(vis));
 63 
 64     int po = num[now_x][now_y]; //该点的编号
 65 
 66     queue<node > que;
 67     que.push(node{now_x,now_y,0});
 68     vis[now_x][now_y] = true;
 69 
 70     while(!que.empty()){
 71 
 72         node tmp = que.front();
 73         que.pop();
 74 
 75         //遇到了其他的点,得到一条边
 76         if(mp[tmp.x][tmp.y] == 'A' || mp[tmp.x][tmp.y] == 'S'){ 
 77             G[po][num[tmp.x][tmp.y]] = min(G[po][num[tmp.x][tmp.y]],tmp.v);
 78         }
 79 
 80         rep__(p,0,4){
 81             
 82             int dx = tmp.x + mv_x[p];
 83             int dy = tmp.y + mv_y[p];
 84 
 85             if(check(dx,dy) && mp[dx][dy] != '#' && !vis[dx][dy]){
 86 
 87                 vis[dx][dy] = true;
 88 
 89                 que.push(node{dx,dy,tmp.v + 1});
 90             }
 91         }
 92     }
 93 
 94 }
 95 
 96 void work(){
 97 
 98     rep__(i,0,n){
 99         rep__(j,0,m){
100             if(mp[i][j] == 'A' || mp[i][j] == 'S'){
101                 bfs(i,j); //每个点跑bfs
102             }
103         }
104     }
105 }
106 
107 //prime板子
108 int prime(){
109 
110     bool VIS[N];
111     int dis[N];
112     memset(VIS, 0, sizeof(VIS));
113 
114     rep(i,1,cnt) dis[i] = G[1][i];
115 
116     VIS[1] = true;
117 
118     rep(i,2,cnt){
119 
120         int x = i;
121         int vv = inf;
122 
123         rep(j,1,cnt){
124             if(!VIS[j] && vv > dis[j]) vv = dis[x = j];
125         }
126         
127         if(x == -1) continue;
128 
129         VIS[x] = 1;
130 
131         rep(j,1,cnt){
132             if(!VIS[j] && dis[j] > G[x][j])
133                 dis[j] = G[x][j];
134         }
135     }
136 
137     int sum = 0;
138     rep(i,1,cnt) sum += dis[i];
139 
140     return sum;
141 }
142 
143 
144 int main(){
145 
146 
147     int T;
148     scanf("%d",&T);
149 
150     while(T--){
151 
152         scanf("%d%d\n",&m,&n);
153 
154         rep__(i,0,n) gets(mp[i]);    
155 
156         set_num();//设置编号
157         init_G(); //初始化G
158         work();
159         
160 
161         // rep(i,1,cnt){
162         //     rep(j,1,cnt) printf("%d",G[i][j]);
163         //     printf("\n");
164         // }
165 
166         // printf("ans\n");
167         printf("%d\n",prime());
168 
169     }
170 
171 
172     getchar();getchar();
173     return 0;
174 }

 

posted @ 2019-07-23 22:37  SummerMingQAQ  阅读(241)  评论(0编辑  收藏  举报