注意边界
https://vjudge.net/problem/UVA-1018
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<fstream>
using namespace std;
const int N=105;
char map[N][N];
struct AA{
int x,y;
AA(int xx=-1,int yy=-1):x(xx),y(yy){}
inline bool operator==(AA a){
return a.x==x&&a.y==y;
}
AA(const AA& a):x(a.x),y(a.y){}
inline bool operator!=(AA a){
return !(a.x==x&&a.y==y);
}
};
AA set[N][N];
AA set_find(AA a){
if(set[a.x][a.y]==AA(-1,-1))return a;
return set[a.x][a.y]=set_find(set[a.x][a.y]);
}
int bridge;
int length;
struct BB{
AA a,b;
int d;
BB(AA aa,AA bb,int dd):a(aa),b(bb),d(dd){}
bool s_find(){
AA p=set_find(a);
AA q=set_find(b);
if(p!=q){
bridge++;
length+=d;
set[p.x][p.y]=q;
return true;
}
return false;
}
};
bool cmp(BB a,BB b){
return a.d<b.d;
}
int n,m;
void dfs(int x,int y,AA a){
if(x<0||x>=n||y<0||y>=m)return;
if(set_find(AA(x,y))!=set_find(a)||map[x][y]=='G'){
if(map[x][y]=='#'){
set[x][y].x=a.x;
set[x][y].y=a.y;
map[x][y]='G';
}
int xx,yy;
for(int i=-1;i<=1;i++)
for(int j=-1;j<=1;j++)
if(map[xx=x+i][yy=y+j]=='#'){
dfs(x+i,y+j,a);
}
}
}
int main(){
int f=1;
while(scanf("%d%d",&n,&m),n&&m){
getchar();
if(f>1){
puts("");
}
printf("City %d\n",f++);
memset(set,-1,sizeof(set));
for(int i=0;i<n;i++){
gets(map[i]);
map[i][m]='.';
}
for(int i=0;i<=m;i++)
map[n][i]='.';
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(map[i][j]=='#'){
map[i][j]='G';
dfs(i,j,AA(i,j));
}
int part=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(map[i][j]=='G'){
if(set_find(AA(i,j))==AA(i,j))
part++;
}
if(part<=1){
puts("No bridges are needed.");
continue;
}
vector<BB> v;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(map[i][j]=='G'){
for(int k=i+1;k<n;k++)
for(int det=-1;det<=1;det++)
if(map[k][j+det]=='G'){
if(set_find(AA(i,j))!=set_find(AA(k,j+det)))
v.push_back(BB(AA(i,j),AA(k,j+det),k-i-1));
}
}
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(map[i][j]=='G'){
for(int k=j+1;k<m;k++)
for(int det=-1;det<=1;det++)
if(map[i+det][k]=='G'){
if(set_find(AA(i,j))!=set_find(AA(i+det,k)))
v.push_back(BB(AA(i,j),AA(i+det,k),k-j-1));
}
}
sort(v.begin(),v.end(),cmp);
bridge=0;
length=0;
int len=v.size();
int cnt=0;
for(int i=0;i<len;i++){
if(v[i].s_find())cnt++;
}
if(bridge==0){
puts("No bridges are possible.");
printf("%d disconnected groups\n",part);
continue;
}
if(bridge==1)
printf("%d bridge of total length %d\n",bridge,length);
else
printf("%d bridges of total length %d\n",bridge,length);
if(part!=bridge+1)
printf("%d disconnected groups\n",part-bridge);
}
}