【codevs1002】搭桥
2016-01-03 19:10
169 查看
题目描述 Description
有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物。现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格的边沿搭建,如下图城市1有5栋建筑物,可以搭建4座桥将建筑物联系起来。城市2有两座建筑物,但不能搭建桥梁将它们连接。城市3只有一座建筑物,城市4有3座建筑物,可以搭建一座桥梁联系两栋建筑物,但不能与第三座建筑物联系在一起。
输入描述 Input Description
在输入的数据中的第一行包含描述城市的两个整数r 和c, 分别代表从北到南、从东到西的城市大小(1 <= r <= 50 and 1 <= c <= 50). 接下来的r 行, 每一行由c 个(“#”)和(“.”)组成的字符.
每一个字符表示一个单元格。“#”表示建筑物,“.”表示空地。
输出描述 Output Description
在输出的数据中有两行,第一行表示建筑物的数目。第二行输出桥的数目和所有桥的总长度。
样例输入 Sample Input
样例1
3 5
#...#
..#..
#...#
样例2
3 5
##...
.....
....#
样例3
3 5
#.###
#.#.#
###.#
样例4:
3 5
#.#..
.....
....#
样例输出 Sample Output
样例1
5
4 4
样例2
2
0 0
样例3
1
0 0
样例4
3
1 1
【题解】
dfs+kruskal 不要妄想读懂我的代码
【代码】
有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物。现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格的边沿搭建,如下图城市1有5栋建筑物,可以搭建4座桥将建筑物联系起来。城市2有两座建筑物,但不能搭建桥梁将它们连接。城市3只有一座建筑物,城市4有3座建筑物,可以搭建一座桥梁联系两栋建筑物,但不能与第三座建筑物联系在一起。
输入描述 Input Description
在输入的数据中的第一行包含描述城市的两个整数r 和c, 分别代表从北到南、从东到西的城市大小(1 <= r <= 50 and 1 <= c <= 50). 接下来的r 行, 每一行由c 个(“#”)和(“.”)组成的字符.
每一个字符表示一个单元格。“#”表示建筑物,“.”表示空地。
输出描述 Output Description
在输出的数据中有两行,第一行表示建筑物的数目。第二行输出桥的数目和所有桥的总长度。
样例输入 Sample Input
样例1
3 5
#...#
..#..
#...#
样例2
3 5
##...
.....
....#
样例3
3 5
#.###
#.#.#
###.#
样例4:
3 5
#.#..
.....
....#
样例输出 Sample Output
样例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; } } } }
相关文章推荐
- 数据泵导入导出
- DNS服务搭建
- JS将毫秒时间戳转换成合适的时间字符串
- 计算机视觉方面2016年重要会议deadline
- Android Studio使用教程
- Android Studio使用教程
- 轻松scrum之旅---敏捷开发故事
- C++程序设计课后习题及解答(第七章)
- 关于HTTPS转载的文章
- Android CardView 简介
- CVPR14与图像视频检索相关的论文
- 数据结构02--队列
- STM32外设驱动篇——DHT11温湿度传感器
- 出乎意料的回答
- xcodeheader search 配置
- 抽象工厂模式
- 数据结构JAVA图的基本操作
- C#使用ping命令检查设备状态
- 图像检索中BOW和LSH的一点理解
- 上天不需要你成功,只需要你尝试。waiting for life is waiting for death!