zoukankan      html  css  js  c++  java
  • codevs 1002 搭桥

     题目描述 Description

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

    输入描述 Input Description

    在输入的数据中的第一行包含描述城市的两个整数rc, 分别代表从北到南、从东到西的城市大小(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

    数据范围及提示 Data Size & Hint

    见描述

    dfs可以解决第一问;

    第二问用最小生成树做

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 using namespace std;
      5 
      6 string s;
      7 
      8 int dx[9]={0,0,0,1,-1,1,1,-1,-1},dy[9]={0,1,-1,0,0,1,-1,1,-1};
      9 
     10 int book[55][55],pos[55][55];
     11 const int N=2505;
     12 int father[N*2];
     13 
     14 struct node{
     15     int u,v,w;
     16     bool operator < (const node &a)const     
     17     {
     18          return w<a.w;
     19      }
     20 }e[N*100];
     21 int map[55][55];
     22 
     23 int n,m;
     24 int ans=0,cnt=0;
     25 
     26 
     27 void dfs(int x,int y)
     28 {
     29     book[x][y]=ans;
     30     for(int i=0;i<=8;i++)
     31     {
     32         if(map[x+dx[i]][y+dy[i]])
     33         {
     34             map[x+dx[i]][y+dy[i]]=0;
     35             dfs(x+dx[i],y+dy[i]);
     36         }
     37     }
     38     return ;
     39     
     40 }
     41 
     42 bool unionn(int x1,int y1,int x2,int y2,int w)
     43 {
     44     if(y2<1||y2>m||x2<1||x2>n||!book[x2][y2]) return 1;
     45     if(book[x1][y1]==book[x2][y2]) return 0;
     46     cnt++;
     47     e[cnt].u=book[x1][y1];
     48     e[cnt].v=book[x2][y2];
     49     e[cnt].w=w-1;
     50     return 1;
     51 }
     52 
     53 void build(int x ,int y)
     54 {
     55     for(int i=x+1; i<=n; i++)
     56         if(!unionn(x,y,i,y,i-x)||!unionn(x,y,i,y+1,i-x)||!unionn(x,y,i,y-1,i-x))
     57             break;
     58     for(int i=x-1; i>0; i--)
     59         if(!unionn(x,y,i,y,x-i)||!unionn(x,y,i,y+1,x-i)||!unionn(x,y,i,y-1,x-i))
     60             break;
     61     for(int i=y+1; i<=m; i++)
     62         if(!unionn(x,y,x,i,i-y)||!unionn(x,y,x-1,i,i-y)||!unionn(x,y,x+1,i,i-y))
     63             break;
     64     for(int i=y-1; i>0; i--)
     65         if(!unionn(x,y,x,i,y-i)||!unionn(x,y,x-1,i,y-i)||!unionn(x,y,x-1,i,y-i))
     66             break;
     67 }
     68 
     69 void work()
     70 {
     71     for(int i=1;i<=n;i++)
     72     for(int j=1;j<=m;j++)
     73     {
     74         if(pos[i][j])build(i,j);
     75     }
     76     return ;
     77 }
     78 
     79 int find(int x)
     80 {
     81     if(father[x]!=x)father[x]=find(father[x]);
     82     return father[x];
     83 }
     84 
     85 int main()
     86 {
     87     scanf("%d%d",&n,&m);
     88     for(int i=1;i<=n*m;i++)father[i]=i;
     89     for(int i=1;i<=n;i++)
     90     {
     91         cin>>s;
     92         for(int j=0;j<s.size();j++)
     93         {
     94             if(s[j]=='#')pos[i][j+1]=map[i][j+1]=1;
     95             else map[i][j+1]=0;
     96             //if(map[i][j+1]==1&&map[i-1][j+1]==0&&map[i][j]==0)cnt++;
     97         }
     98             
     99     }
    100     //printf("%d",cnt);
    101     for(int i=1;i<=n;i++)
    102     for(int j=1;j<=m;j++)
    103     {
    104         if(map[i][j]==1)
    105         {
    106             map[i][j]=0;
    107             dfs(i,j);
    108             ans++;
    109         }
    110     }
    111     printf("%d
    ",ans);
    112     int sum=0;
    113     for(int i=1;i<=ans;i++)father[i]=i;
    114     work();
    115     sort(e+1,e+cnt+1);
    116     ans=0;
    117     for(int i=1;i<=cnt;i++) 
    118     {
    119         int p=find(e[i].u),q=find(e[i].v);
    120         if(p!=q) 
    121         {
    122             father[p]=q;
    123             ans++;
    124             sum+=e[i].w;
    125         }
    126     }
    127     printf("%d %d",ans,sum);
    128     
    129     return 0;
    130 
    131 }
  • 相关阅读:
    UVa 1451 Average (斜率优化)
    POJ 1160 Post Office (四边形不等式优化DP)
    HDU 3507 Print Article (斜率DP)
    LightOJ 1427 Substring Frequency (II) (AC自动机)
    UVa 10245 The Closest Pair Problem (分治)
    POJ 1741 Tree (树分治)
    HDU 3487 Play with Chain (Splay)
    POJ 2828 Buy Tickets (线段树)
    HDU 3723 Delta Wave (高精度+calelan数)
    UVa 1625 Color Length (DP)
  • 原文地址:https://www.cnblogs.com/sssy/p/6852956.html
Copyright © 2011-2022 走看看