Borg Maze POJ - 3026

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

思路:

题目说建立一个通道网络,使得‘S’能到达其他所有'A',且所有通道长度相加最短,可以看出是一个最小生成树,就是建图比较麻烦。

用bfs建图,跑出每个‘S’或‘A’到其他‘S’或‘A’的距离,然后只需要套上最小生成树的板子就OK。

  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(){
 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;
 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         if(mp[tmp.x][tmp.y] == 'A' || mp[tmp.x][tmp.y] == 'S'){
 76             G[po][num[tmp.x][tmp.y]] = min(G[po][num[tmp.x][tmp.y]],tmp.v);
 77         }
 78 
 79         rep__(p,0,4){
 80             
 81             int dx = tmp.x + mv_x[p];
 82             int dy = tmp.y + mv_y[p];
 83 
 84             if(check(dx,dy) && mp[dx][dy] != '#' && !vis[dx][dy]){
 85 
 86                 vis[dx][dy] = true;
 87 
 88                 que.push(node{dx,dy,tmp.v + 1});
 89             }
 90         }
 91     }
 92 
 93 }
 94 
 95 void work(){
 96 
 97     rep__(i,0,n){
 98         rep__(j,0,m){
 99             if(mp[i][j] == 'A' || mp[i][j] == 'S'){
100                 bfs(i,j);
101             }
102         }
103     }
104 }
105 
106 int prime(){
107 
108     bool VIS[N];
109     int dis[N];
110     memset(VIS, 0, sizeof(VIS));
111 
112     rep(i,1,cnt) dis[i] = G[1][i];
113 
114     VIS[1] = true;
115 
116     rep(i,2,cnt){
117 
118         int x = i;
119         int vv = inf;
120 
121         rep(j,1,cnt){
122             if(!VIS[j] && vv > dis[j]) vv = dis[x = j];
123         }
124         
125         if(x == -1) continue;
126 
127         VIS[x] = 1;
128 
129         rep(j,1,cnt){
130             if(!VIS[j] && dis[j] > G[x][j])
131                 dis[j] = G[x][j];
132         }
133     }
134 
135     int sum = 0;
136     rep(i,1,cnt) sum += dis[i];
137 
138     return sum;
139 }
140 
141 
142 int main(){
143 
144     ios::sync_with_stdio(false);
145     cin.tie(0);
146 
147     int T;
148     cin >> T;
149 
150     while(T--){
151 
152         cin >> m >> n;
153         getline(cin,mp[0]);
154 
155         rep__(i,0,n) getline(cin,mp[i]);    //ok
156 
157         set_num();//ok
158         init();//ok
159         work();
160         
161 
162         // rep(i,1,cnt){
163         //     rep(j,1,cnt) cout << G[i][j];
164         //     cout << endl;
165         // }
166 
167         // cout << "ans" << endl;
168         cout << prime() << endl;
169 
170     }
171 
172 
173     getchar();getchar();
174     return 0;
175 }

 

posted on 2019-11-08 20:25 SSummerZzz 阅读(...) 评论(...) 编辑 收藏

导航

统计