codevs 1002 搭桥

1002 搭桥

 时间限制: 1 s

 空间限制: 128000 KB

 题目等级 : 黄金 Gold

题解

题目描述 Description

有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物。现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格的边沿搭建,如下图城市1有5栋建筑物,可以搭建4座桥将建筑物联系起来。城市2有两座建筑物,但不能搭建桥梁将它们连接。城市3只有一座建筑物,城市4有3座建筑物,可以搭建一座桥梁联系两栋建筑物,但不能与第三座建筑物联系在一起。

输入描述 Input Description

在输入的数据中的第一行包含描述城市的两个整数r 和c, 分别代表从北到南、从东到西的城市大小(1 <= <= 50 and 1 <=  c <= 50). 接下来的r 行, 每一行由个(“#”)和(“.”)组成的字符. 每一个字符表示一个单元格。“#”表示建筑物,“.”表示空地。

扫描二维码关注公众号,回复: 2463373 查看本文章

输出描述 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,最小生成树,做题需要耐心。

#include <iostream>
using namespace std;
#include <cstdio>
#include <algorithm>
#include <cstring>
 
const int MaxN=1001;
 
struct city{
    int x,y;
}h[MaxN];
 
struct Edge{
    int u,v,w;
    friend bool operator< (Edge a,Edge b){return a.w<b.w;}
}map[MaxN*MaxN];
 
int hash[MaxN][MaxN],t[MaxN];
int n,m,L,s,ID=0;
char c[MaxN][MaxN];
 
void init(){
   cin>>n>>m;
   int i,j;
   for(i=1;i<=n;i++)
     for(j=1;j<=m;j++)
     {
        cin>>c[i][j];
        if(c[i][j]=='#'){//统计有多少个地皮 
            L++;//记录下来 
            h[L].x=i;
            h[L].y=j;
        }
    }
}
 
void Flood_fill(int x,int y,int ID){
    if(x<1 || y<1 || x>n || y>m || hash[x][y] || c[x][y]=='.')return;
     hash[x][y]=ID;
     if(x<n)Flood_fill(x+1,y,ID);
     if(y<m)Flood_fill(x,y+1,ID);
     if(x>1)Flood_fill(x-1,y,ID);
     if(y>1)Flood_fill(x,y-1,ID);
     if(x<n && y<m)Flood_fill(x+1,y+1,ID);
     if(x<n && y>1)Flood_fill(x+1,y-1,ID);
     if(x>1 && y>1)Flood_fill(x-1,y-1,ID);
     if(x>1 && y<m)Flood_fill(x-1,y+1,ID);
}
 
int find(int x){
    if(t[x]==-1)return x;
    else return t[x]=find(t[x]);
}
 
void Kruskal(){
    sort(map+1,map+s+1);
    int x,y,k=0,i=1,cost=0;
    while(i<=s){
        x=find(map[i].u);
        y=find(map[i].v);
        if(x!=y){
            cost+=map[i].w;
            k++;
            t[x]=y;
        }
        i++;
    }
    cout<<k<<" "<<cost;
}
 
int len(int x1,int y1,int x2,int y2){
	if(abs(x1-x2)<2)return abs(y1-y2)-1;
	if(abs(y1-y2)<2)return abs(x1-x2)-1;
	return 1000;
}
 
void add(int i,int j,int k,int l){
    s++;
    map[s].u=hash[i][j];
    map[s].v=hash[k][l];
    map[s].w=len(i,j,k,l);
}
 
void work(){
    int i,j,k,l;
    memset(hash,false,sizeof(hash));
    memset(t,-1,sizeof(t));
    for(i=1;i<=L;i++)
      if(!hash[h[i].x][h[i].y])
        Flood_fill(h[i].x,h[i].y,++ID);
    cout<<ID<<endl;
    for(i=1;i<=n;i++)
     for(j=1;j<=m;j++)
      for(k=1;k<=n;k++)
        for(l=1;l<=m;l++)
          if(hash[i][j] && hash[k][l]&& !(i==k && j==l) && hash[i][j]!=hash[k][l])  
             add(i,j,k,l);
    Kruskal();
}
 
int main(){
   init();
   work();
   return 0;
}

猜你喜欢

转载自blog.csdn.net/xyqqwer/article/details/81190173