codevs 1002 搭桥
codevs 第一道题
先贴描述
有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物。现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格的边沿搭建,如下图城市1有5栋建筑物,可以搭建4座桥将建筑物联系起来。城市2有两座建筑物,但不能搭建桥梁将它们连接。城市3只有一座建筑物,城市4有3座建筑物,可以搭建一座桥梁联系两栋建筑物,但不能与第三座建筑物联系在一起。
在输入的数据中的第一行包含描述城市的两个整数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
见描述
这题恶心的要死;
做完整个人都是蒙比的;
刚开始连思路都没有,还是看了题解才知道用搜索加最小生成树来做;
然后我开始敲代码;
第一遍敲完编译不通过,改了很久编译才通过;
然后贴数据输出;
结果连城市的数量都错;
然后我就努力的调啊调;
最后我发现,字符第一个元素是0,我tm却从1开始循环(这告我们脑子是个好东西);
然后继续贴数据;
第二个样例又不过了;
好,继续改;
然后,4向搜索问题一大堆。。(这告诉我们认真敲代码很重要);
然后样例都过了;
然后提交: 全wa,0分(我勒个擦!!);
全wa后我开始思考为什么全wa;
我发现可能是输入的问题;
然后改输入,a了一个点;
可能不是输入的问题;
然后,我又把题目读了一边;
如果某两个单元格有一个点相联系,则它们属于同一座建筑物。
我日;
我是按4向连接的;
好吧改一下;
改成八项;
然后;
ac了!;
好吧,说一下思路:
先把所有的数据读入;
建立一个imap数组用来把读入的数据弄成数字;
‘.’是0;
‘#’是-1;
然后循环全部,找到-1就开始广搜,把相连的-1变成不同楼房的标记;
然后循环每一个标记,上下左右四个方向搜索;
注意:
因为是桥在边上,所以 要同时搜索相邻的两个格;
然后,把搜到的边都记下来,跑一遍最小生成树就ac了;
附代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m,imap[51][51],ncon=0; char cmap[51][51]; const int dx[9]={0,-1,-1,0,1,1,1,0,-1}; const int dy[9]={0,0,1,1,1,0,-1,-1,-1}; struct node { int name1,name2,dis; }; struct node edge[100011]; int fa[2501],num=0,ans=0; int find(int x) { if(fa[x]==x) return x; fa[x]=find(fa[x]); return fa[x]; } void big(int x,int y,int dis) { imap[x][y]=dis; for(int i=1;i<=8;i++) { if(x+dx[i]>0&&x+dx[i]<=n&&y+dy[i]>0&&y+dy[i]<=m) { if(imap[x+dx[i]][y+dy[i]]==-1) { big(x+dx[i],y+dy[i],dis); } } } } void edge_add(int from,int to,int dis) { num++; edge[num].name1=from; edge[num].name2=to; edge[num].dis=dis; } void edge_find_up(int x,int y,int from,int dis) { if(y-1>0&&x-1>0) if(imap[x-1][y-1]!=0&&imap[x-1][y-1]!=from) edge_add(from,imap[x-1][y-1],dis); if(y+1<=m&&x-1>0) if(imap[x-1][y+1]!=0&&imap[x-1][y+1]!=from) edge_add(from,imap[x-1][y+1],dis); if(x-1>0) { if(imap[x-1][y]!=0&&imap[x-1][y]!=from) edge_add(from,imap[x-1][y],dis); else if(imap[x-1][y]!=from) edge_find_up(x-1,y,from,dis+1); } } void edge_find_down(int x,int y,int from,int dis) { if(y-1>0&&x+1<=n) if(imap[x+1][y-1]!=0&&imap[x+1][y-1]!=from) edge_add(from,imap[x+1][y-1],dis); if(y+1<=m&&x+1<=n) if(imap[x+1][y+1]!=0&&imap[x+1][y+1]!=from) edge_add(from,imap[x+1][y+1],dis); if(x+1<=n) { if(imap[x+1][y]!=0&&imap[x+1][y]!=from) { // printf("%d %d\n",x+1,y); edge_add(from,imap[x+1][y],dis); } else if(imap[x+1][y]!=from) edge_find_down(x+1,y,from,dis+1); } } void edge_find_lift(int x,int y,int from,int dis) { if(x-1>0&&y-1>0) if(imap[x-1][y-1]!=0&&imap[x-1][y-1]!=from) edge_add(from,imap[x-1][y-1],dis); if(x+1<=n&&y-1>0) if(imap[x+1][y-1]!=0&&imap[x+1][y-1]!=from) edge_add(from,imap[x+1][y-1],dis); if(y-1>0) { if(imap[x][y-1]!=0&&imap[x][y-1]!=from) edge_add(from,imap[x][y-1],dis); else if(imap[x][y-1]!=from) edge_find_lift(x,y-1,from,dis+1); } } void edge_find_right(int x,int y,int from,int dis) { if(x-1>0&&y+1<=m) if(imap[x-1][y+1]!=0&&imap[x-1][y+1]!=from) edge_add(from,imap[x-1][y+1],dis); if(x+1<=n&&y+1<=m) if(imap[x+1][y+1]!=0&&imap[x+1][y+1]!=from) edge_add(from,imap[x+1][y+1],dis); if(y+1<=m) { if(imap[x][y+1]!=0&&imap[x][y+1]!=from) { // printf("%d %d\n",x,y+1); edge_add(from,imap[x][y+1],dis); } else if(imap[x][y+1]!=from) edge_find_right(x,y+1,from,dis+1); } } void edge_build(int from,int x,int y) { if(x-1>0) edge_find_up(x-1,y,from,1); if(x+1<=n) edge_find_down(x+1,y,from,1); if(y-1>0) edge_find_lift(x,y-1,from,1); if(y+1<=m) edge_find_right(x,y+1,from,1); } int cmp(struct node a,struct node b) { return a.dis<b.dis; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { cin>>cmap[i]+1; for(int j=1;j<=m;j++) { if(cmap[i][j]=='#') imap[i][j]=-1; } } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(imap[i][j]==-1) { ncon++; big(i,j,ncon); } } } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(imap[i][j]!=0) edge_build(imap[i][j],i,j); } } sort(edge+1,edge+num+1,cmp); int head=0,zh=0,xx,yy; for(int i=1;i<=ncon;i++) fa[i]=i; while(head<=ncon&&zh<=num) { zh++; xx=find(edge[zh].name1),yy=find(edge[zh].name2); if(xx!=yy) { ans+=edge[zh].dis; fa[xx]=yy; head++; } } /*for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) printf(" %d",imap[i][j]); printf("\n"); }*/ printf("%d\n%d %d\n",ncon,head,ans); return 0; }