题目链接:https://vjudge.net/problem/POJ-3026
思路:
题目说建立一个通道网络,使得‘S’能到达其他所有'A',且所有通道长度相加最短,可以看出是一个最小生成树,就是建图比较麻烦。
用bfs建图,跑出每个‘S’或‘A’到其他‘S’或‘A’的距离,然后只需要套上最小生成树的板子就OK。
1 #include 2 #include 3 #include 4 #include<string> 5 #include 6 #include 7 #include 8 #include 9 #include 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 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 }