rt,样例已过,谢谢QAQ
#include<bits/stdc++.h>
using namespace std;
const int N = 51,M = 2501;
int n,m,a[N][N],f[M],cnt,cntt,ans,sum,id,CY;
struct ID {int x,y;}Cy[M];
struct edge {int u,v,d;}e[M * M];
bool cmp(edge x,edge y) {
return x.d < y.d;
}
int find(int x) {
if(x == f[x]) return x;
return f[x] = find(f[x]);
}
void kruskal() {
sort(e + 1,e + cntt + 1,cmp);
for(int i = 1;i <= cntt;i++) {
if(find(e[i].u) != find(e[i].v)) {
f[find(e[i].u)] = find(e[i].v);
ans++,sum += e[i].d,cnt--;
}
}
}
int main() {
while(1) {
scanf("%d%d",&n,&m);
if(n == 0 && m == 0) break;
memset(a,0,sizeof(a)); int K = max(n,m);
cnt = cntt = ans = sum = CY = 0;
for(int i = 0;i <= K * K + 1;i++) f[i] = i;
for(int i = 0;i < n;i++) {
string s; cin >> s;
for(int j = 1;j <= m;j++) {
if(s[j - 1] == '#') {
a[i + 1][j] = 1,cnt++,Cy[++CY] = ID{i + 1,j};
if(i && a[i][j - 1])
f[find(i * K + j)] = find((i - 1) * K + j - 1),cnt--;
if(i && a[i][j] && !a[i][j - 1])
f[find(i * K + j)] = find((i - 1) * K + j),cnt--;
if(i && a[i][j + 1] && !a[i][j])
f[find(i * K + j)] = find((i - 1) * K + j + 1),cnt--;
if(a[i + 1][j - 1] && !a[i][j - 1] && !a[i][j])
f[find(i * K + j)] = find(i * K + j - 1),cnt--;
} else a[i + 1][j] = 0;
}
}
if(id) printf("\n");
printf("City %d\n",++id);
if(cnt <= 1) {
printf("No bridges are needed.\n");
continue;
}
for(int i = 1;i <= CY;i++){
int I = Cy[i].x,J = Cy[i].y;
for(int ii = I;ii <= n;ii++){
for(int k = -1;k <= 1;k++){
int II = ii,JJ = J + k,dist = abs(I - II) - 1;
if(!a[II][JJ]) continue;
if(dist > 0)
e[++cntt] = {(I - 1) * K + J,(II - 1) * K + JJ,dist};
}
}
for(int j = J;j <= m;j++){
for(int k = -1;k <= 1;k++){
int II = I + k,JJ = j,dist = abs(J - JJ) - 1;
if(!a[II][JJ]) continue;
if(dist > 0)
e[++cntt] = {(I - 1) * K + J,(II - 1) * K + JJ,dist};
}
}
}
kruskal();
if(!ans) printf("No bridges are possible.\n");
else {
if(ans == 1) printf("%d bridge of total length %d\n",ans,sum);
else printf("%d bridges of total length %d\n",ans,sum);
} if(cnt > 1) printf("%d disconnected groups\n",cnt);
}
return 0;
}