• 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
    ",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 }
  • 相关阅读:
    深入理解javascript原型和闭包(1)——一切都是对象
    深入理解javascript原型和闭包(2)——函数与对象的关系
    js 的function为什么可以添加属性
    Nodejs入门
    js数组的比较
    对Array.prototype.slice.call()方法的理解
    elementUI el-select 多选情况下包含全部选项,及获得选中项的label
    JS对象,获取key和value
    elementUI实现前端分页
    JavaScript(js)处理的HTML事件、键盘事件、鼠标事件
  • 原文地址:https://www.cnblogs.com/fujudge/p/7577758.html
Copyright © 2020-2023  润新知