在输入的数据中的第一行包含描述城市的两个整数r 和c, 分别代表从北到南、从东到西的城市大小(1 <= r <= 50 and 1 <= c <= 50). 接下来的r 行, 每一行由c 个(“#”)和(“.”)组成的字符. 每一个字符表示一个单元格。“#”表示建筑物,“.”表示空地。
在输出的数据中有两行,第一行表示建筑物的数目。第二行输出桥的数目和所有桥的总长度。
样例1
3 5
#...#
..#..
#...#
样例2
3 5
##...
.....
....#
样例3
3 5
#.###
#.#.#
###.#
样例4:
3 5
#.#..
.....
....#
样例1
5
4 4
样例2
2
0 0
样例3
1
0 0
样例4
3
1 1
【题解】
dfs+kruskal 不要妄想读懂我的代码
【代码】#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; int sx[8]={1,1,1,0,0,-1,-1,-1}; int sy[8]={1,0,-1,1,-1,1,0,-1}; int n,m,tot,num,u,v,p,q,side,sum,sidesum; char s[100]; int a[100][100],f[2505][2505],fa[3000]; struct hp{ int x,y,z; }b[1000000]; bool pd; inline void dfs(int s,int t){ for (int i=0;i<8;++i){ int x=s+sx[i],y=t+sy[i]; if (x>0&&x<=n&&y>0&&y<=m&&a[x][y]==-1){ a[x][y]=tot; dfs(x,y); } } } int cmp(hp a,hp b){ return a.z<b.z; } int find(int x){ if (x==fa[x]) return x; fa[x]=find(fa[x]); return fa[x]; } int merge(int x,int y){ int f1=find(x); int f2=find(y); fa[f1]=f2; } int main(){ scanf("%d%d\n",&n,&m); for (int i=1;i<=n;++i){ gets(s); for (int j=1;j<=m;++j) if (s[j-1]=='#') a[i][j]=-1; } for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) if (a[i][j]==-1){ tot++; a[i][j]=tot; dfs(i,j); } printf("%d\n",tot); if (tot==1){ printf("0 0\n"); return 0; } /* for (int i=1;i<=n;++i){ for (int j=1;j<=m;++j) printf("%d",a[i][j]); printf("\n"); }*/ memset(f,127/3,sizeof(f)); for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) for (int k=1;k<=n;++k) for (int l=1;l<=m;++l){ u=abs(i-k); v=abs(j-l); if (a[i][j]!=0&&a[k][l]!=0&&a[i][j]!=a[k][l]&&(u<=1||v<=1)){ if (u<=1) f[a[i][j]][a[k][l]]=min(f[a[i][j]][a[k][l]],v-1); else if (v<=1) f[a[i][j]][a[k][l]]=min(f[a[i][j]][a[k][l]],u-1); f[a[k][l]][a[i][j]]=f[a[i][j]][a[k][l]]; } } // for (int i=1;i<=tot;++i) // for (int j=1;j<=tot;++j) // if (f[i][j]==0) f[i][j]=707406378; /* for (int i=1;i<=tot;++i){ for (int j=1;j<=tot;++j) printf("%d ",f[i][j]); printf("\n"); }*/ num=tot-1; for (int i=1;i<=tot;++i){ pd=false; for (int j=1;j<=tot;++j) if (f[i][j]!=707406378){ pd=true; break; } if (pd==false) num--; } num=max(num,0); if (num==0){ printf("0 0"); return 0; } printf("%d ",num); for (int i=1;i<tot;++i) for (int j=i+1;j<=tot;++j) if (i!=j&&f[i][j]!=707406378){ side++; b[side].x=i; b[side].y=j; b[side].z=f[i][j]; } // for (int i=1;i<=side;++i) // printf("%d %d %d\n",b[i].x,b[i].y,b[i].z); sort(b+1,b+side+1,cmp); for (int i=1;i<=tot;++i) fa[i]=i; for (int i=1;i<=side;++i){ if (find(b[i].x)!=find(b[i].y)){ merge(b[i].x,b[i].y); sum++; sidesum+=b[i].z; if (num==sum){ printf("%d\n",sidesum); return 0; } } } }