codevs1002: 搭桥

题目描述 Description

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

输入描述 Input Description

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

 

输出描述 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

数据范围及提示 Data Size & Hint

见描述

题解

暴力出奇迹,建边以后kruskal,码农题啊。。。

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #define maxn 60
  5 using namespace std;
  6 int u[10]={0,0,1,-1,1,1,-1,-1},p[10]={1,-1,0,0,-1,1,-1,1};
  7 int ux[20]={2,-2,0,0,2,2,-2,-2,1,-1,1,-1},px[20]={0,0,2,-2,1,-1,1,-1,2,2,-2,-2};
  8 int fa[maxn*maxn],a[maxn][maxn];
  9 int n,m,ans,answ,ecnt,head[maxn*maxn];
 10 char str[60];
 11 struct edge{
 12     int u,v,w,next;
 13 }E[maxn*maxn*4];
 14 void add(int u,int v,int w)
 15 {
 16     E[++ecnt].u=u;
 17     E[ecnt].v=v;
 18     E[ecnt].w=w;
 19     E[ecnt].next=head[u];
 20     head[u]=ecnt;
 21 }
 22 bool ok(int x,int y)
 23 {
 24     if(x<1||y<1||x>n||y>m)return false;
 25     return true;
 26 }
 27 int find(int x)
 28 {
 29     return x==fa[x]?x:fa[x]=find(fa[x]);
 30 }
 31 void build(int x,int y,int z)
 32 {
 33     for(int i=x ; i>=1 ; --i)
 34         if(a[i][y])
 35         {
 36             int fy=find((i-1)*m+y);
 37             if(z!=fy)
 38             {
 39                 add(z,(i-1)*m+y,x-i-1);
 40                 break;
 41             }
 42         }
 43     for(int i=y ; i>=1 ; --i)
 44         if(a[x][i])
 45         {
 46             int fy=find((x-1)*m+i);
 47             if(z!=fy)
 48             {
 49                 add(z,(x-1)*m+i,y-i-1);
 50                 break;
 51             }
 52         }
 53     for(int i=x ; i>=1 ; --i)
 54         if(a[i][y+1]&&y<m)
 55         {
 56             int fy=find((i-1)*m+y+1);
 57             if(z!=fy)
 58             {
 59                 add(z,(i-1)*m+y+1,x-i-1);
 60                 break;
 61             }
 62         }
 63     for(int i=x ; i>=1 ; --i)
 64         if(a[i][y-1]&&y>1)
 65         {
 66             int fy=find((i-1)*m+y-1);
 67             if(z!=fy)
 68             {
 69                 add(z,(i-1)*m+y-1,x-i-1);
 70                 break;
 71             }
 72         }
 73     for(int i=y ; i>=1 ; --i)
 74         if(a[x-1][i]&&x>1)
 75         {
 76             int fy=find((x-2)*m+i);
 77             if(z!=fy)
 78             {
 79                 add(z,(x-2)*m+i,y-i-1);
 80                 break;
 81             }
 82         }
 83     for(int i=y ; i>=1 ; --i)
 84         if(a[x+1][i]&&x<n)
 85         {
 86             int fy=find(x*m+i);
 87             if(z!=fy)
 88             {
 89                 add(z,x*m+i,y-i-1);
 90                 break;
 91             }
 92         }
 93 }
 94 bool cmp(edge x,edge y)
 95 {
 96     return x.w<y.w;
 97 }
 98 int main()
 99 {
100     scanf("%d%d",&n,&m);
101     for(int i=1 ; i<=n ; ++i)
102     {
103         for(int j=1 ; j<=m ; ++j)
104             fa[(i-1)*m+j]=(i-1)*m+j;
105     }
106     for(int i=1 ; i<=n ; ++i)
107     {
108         scanf("%s",str+1);
109         for(int j=1 ; j<=m ; ++j)
110         {
111             if(str[j]=='#')
112             {
113                 a[i][j]=1;
114                 ++ans;
115             }
116         }
117     }
118     for(int i=1 ; i<=n ; ++i )
119         for(int j=1 ; j<=m ; ++j )
120         {
121             if(!a[i][j])continue;
122             for(int k=0 ; k<8 ; ++k)
123             {
124                 int dx=i+u[k];int dy=j+p[k];
125                 if(ok(dx,dy)&&a[dx][dy])
126                 {
127                     int fx=find((i-1)*m+j);
128                     int fy=find((dx-1)*m+dy);
129                     if(fx!=fy)
130                     {
131                         --ans;
132                         fa[fy]=fx;
133                     }
134                 }
135             }
136         }
137     printf("%d\n",ans);    
138     ans=0;
139     for(int i=1 ; i<=n ; ++i )
140         for(int j=1 ; j<=m ; ++j )
141         {
142             if(!a[i][j])continue;
143             int tmp=find((i-1)*m+j);
144             build(i,j,tmp);
145         }
146     sort(E+1,E+1+ecnt,cmp);
147     for(int i=1 ; i<=ecnt ; ++i)
148     {
149         int u=E[i].u;
150         int v=E[i].v;
151         int fx=find(u);int fy=find(v);
152         if(fx!=fy)
153         {
154             ++ans;
155             answ+=E[i].w;
156             fa[fy]=fx;
157         }
158     }
159     printf("%d %d",ans,answ);
160     return 0;
161 }

 

posted @ 2017-09-22 23:38 傅judge 阅读(...) 评论(...) 编辑 收藏