codevs 1002 搭桥
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs 1002 搭桥相关的知识,希望对你有一定的参考价值。
题目描述 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+krustal。
先搜索出每栋不同的楼,并且计算楼与楼之间的间隔。
再利用最小生成树算法将其可联通边联通即可。
#include<iostream> #include<algorithm> using namespace std; char a[60][60]; int book[60][60]; int fx[3601]; int n,m; int dx[9]={0,0,0,1,-1,1,1,-1,-1},dy[9]={0,1,-1,0,0,1,-1,1,-1}; int cnt=0,cnt_b=0; struct node{ int s,f,w; }t[3601]; bool cmp(const node &a,const node &b) { return a.w<b.w; } void dfs(int x,int y) { book[x][y]=cnt; for(int i=1;i<=8;++i) { int tx=x+dx[i],ty=y+dy[i]; if(a[tx][ty]==‘#‘) { a[tx][ty]=‘.‘; dfs(tx,ty); } } } void find(int x,int y) { for(int i=1;i<=m;++i) { if(y+i>m)break; if(book[x][y+1]==book[x][y])break; for(int j=1;j<=8;++j) { int tx=x+dx[j],ty=y+i+dy[j]; if(book[tx][ty]!=0&&book[tx][ty]!=book[x][y]) { ++cnt_b; t[cnt_b].s=book[x][y]; t[cnt_b].f=book[tx][ty]; t[cnt_b].w=i; } } } for(int i=1;i<=n;++i) { if(x+i>n)break; if(book[x+1][y]==book[x][y])break; for(int j=1;j<=8;++j) { int tx=x+i+dx[j],ty=y+dy[j]; if(book[tx][ty]!=0&&book[tx][ty]!=book[x][y]) { ++cnt_b; t[cnt_b].s=book[x][y]; t[cnt_b].f=book[tx][ty]; t[cnt_b].w=i; } } } } int find(int n) { if(fx[n]==n)return n; else return fx[n]=find(fx[n]); } bool merge(int s,int f) { int a=find(s),b=find(f); if(a!=b) { fx[b]=a; return 1; } else return 0; } int main() { cin>>n>>m; for(int i=1;i<=n*m;++i)fx[i]=i; for(int i=1;i<=n;++i) for(int j=1;j<=m;++j)cin>>a[i][j]; for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) { if(a[i][j]==‘#‘) { a[i][j]=‘.‘; ++cnt; dfs(i,j); } } } /* for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) { cout<<book[i][j]<<" "; } cout<<endl; } */ for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) { if(book[i][j]!=0)find(i,j); } } // for(int i=1;i<=cnt_b;++i)cout<<t[i].s<<" "<<t[i].f<<" "<<t[i].w<<endl; sort(t+1,t+cnt_b+1,cmp); int k=0,sum=0; for(int i=1;i<=cnt_b;++i) { if(merge(t[i].s,t[i].f)) { ++k; sum+=t[i].w; } } cout<<cnt<<endl; cout<<k<<" "<<sum; return 0; }
以上是关于codevs 1002 搭桥的主要内容,如果未能解决你的问题,请参考以下文章