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

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 黄金 Gold
    题目描述 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

    见描述

      1 #include <algorithm>
      2 #include <iostream>
      3 #include <cstdio>
      4 #include <cmath>
      5 
      6 #define N 10015
      7 
      8 using namespace std;
      9 
     10 int r,c,num,cnt;
     11 int bridge,tot,building;
     12 int fa[N*10];
     13 char s;
     14 
     15 struct node_map
     16 {
     17     int x,y;
     18 }map[N*10];
     19 
     20 struct node_edge
     21 {
     22     int from,to,dis;
     23 }edge[N*10];
     24 
     25 void init()
     26 {
     27     for(int i=1;i<=r*c;i++)
     28         fa[i]=i;
     29 }
     30 
     31 int find(int x)
     32 {
     33     if(fa[x]!=x)
     34         return fa[x]=find(fa[x]);
     35     return fa[x];
     36 }
     37 
     38 void add(int from,int to,int dis)
     39 {
     40     cnt++;
     41     edge[cnt].from=from;
     42     edge[cnt].to=to;
     43     edge[cnt].dis=dis;
     44 }
     45 
     46 void work(int a,int b)
     47 {
     48     int dis_x=abs(map[a].x-map[b].x);
     49     int dis_y=abs(map[a].y-map[b].y);
     50     if(dis_x>=2&&dis_y>=2)    return ;
     51     if((dis_x<=1&&dis_y<=1))
     52         if(find(a)==find(b)) return ;
     53         else
     54             fa[find(a)]=find(b);
     55     if(dis_x>=2) add(a,b,dis_x-1);
     56     else add(a,b,dis_y-1);
     57 }
     58 
     59 bool cmp(node_edge a,node_edge b)
     60 {
     61     return a.dis<b.dis;
     62 }
     63 
     64 void kruskal()
     65 {
     66     sort(edge+1,edge+cnt+1,cmp);
     67     for(int i=1;i<=cnt;i++)
     68     {
     69         int fa_x=find(edge[i].from),fa_y=find(edge[i].to);
     70         if(fa_x!=fa_y)
     71         {
     72             bridge++;
     73             fa[fa_x]=fa_y;
     74             tot+=edge[i].dis;
     75         }
     76     }
     77 }
     78 
     79 int main()
     80 {
     81     scanf("%d%d",&r,&c);
     82     init();
     83     for(int i=1;i<=r;i++)
     84         for(int j=1;j<=c;j++)
     85         {
     86             cin>>s;
     87             if(s=='#')
     88             {
     89                 num++;
     90                 map[num].x=i;
     91                 map[num].y=j;
     92                 for(int k=1;k<num;k++)    work(k,num);
     93             }
     94         }
     95     for(int i=1;i<=num;i++)
     96         if(i==fa[i]) building++;
     97     kruskal();
     98     printf("%d
    %d %d",building,bridge,tot);
     99     return 0;
    100 }
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    cvsmooth平滑处理函数
    对图像频率的一些理解
    VIM 如何切换buffer
    Mplab X IDE 安装DMCI
    测试 使用橘子曰
    wlr设置 Blog Ping
    wlr快捷键
    使用Windows Live Writer写文章时不要用360清除垃圾
    如何将Windows live writer草稿转存到其他电脑上
    使用windows live writer写cnblog-1 安装wlr
  • 原文地址:https://www.cnblogs.com/Shy-key/p/6670764.html
Copyright © 2011-2022 走看看