zoukankan      html  css  js  c++  java
  • [FZYZOJ 1038] 隧道

    P1038 -- 隧道

    时间限制:1000MS      内存限制:65536KB

    Description

    一座小镇正在着手建造自己的地铁线路网。小镇坐落在许多小岛上,小岛之间通过隧道或者桥梁连接。地铁就在这些已有的桥梁和隧道的基础上建成。由于地铁主要是在地下,所以桥梁用得越少越好。小镇的居民希望能够仅通过地铁就能在任意两座小岛之间往返旅行。幸运的是,我们有足够多的隧道和桥梁来满足这个要求,所以不需要建造新的隧道或桥梁。你的任务是计算需要构建这样一个地铁线路网最少需要用到几座桥梁。

    Input Format

    输入包括K+M+1行,第一行包括三个数:N(1≤N≤10000),K(1≤K≤12000),M(1≤M≤12000)。其中N为小岛数量,K为隧道数量,M为桥梁数量,以下K行每行有两个数,表示相应的隧道连接的小岛的编号,再往下M行每行用同样的方式描述一座桥梁。

    Output Format

    输出仅包括一个数,即最少需要用到的桥梁数。

    Sample Input

    6 3 4
    1 2
    2 3
    4 5
    1 3
    3 4
    4 6
    5 6

    Sample Output

    2

    【题解】

    本题,其实有很多地方是无用的:

    “幸运的是,我们有足够多的隧道和桥梁来满足这个要求”

    这句话保证了,我们肯定能够将这些小岛联通。

    那么,我们只要并查集搞定隧道,然后再找出有几个根,即可搞定了,根本不需要读入m和后面的桥梁。

    代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int pre[10010],r[10010];
     4 int findset(int x){
     5     int r=x;
     6     while(pre[r]!=r) r=pre[r];
     7     int i=x,j;
     8     while(i!=r) {
     9         j=pre[i];
    10         pre[i]=r;
    11         i=j;
    12     }
    13     return r;
    14 }
    15 int main() {
    16     int n,k;
    17     scanf("%d%d%*d",&n,&k);
    18     for (int i=1;i<=n;++i) pre[i]=i;
    19     while(k--) {
    20         int a,b,f1,f2;
    21         scanf("%d%d",&a,&b);
    22         f1=findset(a);
    23         f2=findset(b);
    24         if(f1!=f2) pre[f1]=f2;
    25     }
    26     int cnt=0;
    27     for (int i=1;i<=n;++i) if(pre[i]==i) cnt++;
    28     printf("%d
    ",cnt-1);
    29     return 0;
    30 }
    View Code
    这篇文章由TonyFang发布。 所有解释权归TonyFang所有。 Mailto: tony-fang@map-le.net
  • 相关阅读:
    JavaScript最佳实践
    Ionic2学习笔记(3):Pipe
    广商14级软件工程分数:第十一回合
    Ionic2学习笔记(2):自定义Component
    Ionic2学习笔记(1):新建一个页面
    Ionic2学习笔记(0):HelloWorld
    采用Kettle分页处理大数据量抽取任务
    广商14级软件工程分数:第十回合
    广商14级软件工程分数:第九回合
    广商14级软件工程-项目介绍视频汇总
  • 原文地址:https://www.cnblogs.com/TonyNeal/p/fzyzoj1038.html
Copyright © 2011-2022 走看看