• D.加边的无向图


    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 32768K,其他语言65536K
    64bit IO Format: %lld

    题目描述

    给你一个 n 个点,m 条边的无向图,求至少要在这个的基础上加多少条无向边使得任意两个点可达~ 

    输入描述:

    第一行两个正整数 n 和 m 。
    接下来的m行中,每行两个正整数 i 、 j ,表示点i与点j之间有一条无向道路。

    输出描述:

    输出一个整数,表示答案
    示例1

    输入

    4 2
    1 2
    3 4

    输出

    1

    备注:

    对于100%的数据,有n,m<=100000。

    分析:并查集。

     1 #include<cstdio>
     2 #include<cstring>
     3 
     4 int N,M;//N个点M条边 
     5 int pre[200012];//pre[i]=x表示点i的父亲节点为点x 
     6 int a[200012];
     7 void init()//初始化N个元素pre[x]=x,即开始时有N个集合 
     8 {
     9     for(int i=0;i<=N;i++) pre[i]=i;
    10 }
    11 
    12 int find(int x)//查询某点所在树的根 
    13 {
    14     int root=x;
    15     while(pre[root]!=root)
    16     root=pre[root];
    17     
    18     int i=x,k;
    19     while(k!=root)//路径压缩,让x所在树的所有节点直接指向根节点 
    20     {
    21         k=pre[i];
    22         pre[i]=root;
    23         i=k;
    24     }
    25     return root; 
    26 }
    27 
    28 int unite(int x,int y)
    29 {
    30     int rootx=find(x),rooty=find(y);
    31     if(rootx!=rooty)
    32     {pre[rootx]=pre[rooty];return 1;}
    33     return 0;
    34 }
    35 
    36 int main()
    37 {
    38     scanf("%d",&N);
    39         scanf("%d",&M);
    40         init();
    41         int x,y,ans=N;
    42         for(int i=1;i<=M;i++)
    43         {
    44             scanf("%d%d",&x,&y);
    45             ans-=unite(x,y);
    46         }
    47         printf("%d
    ",ans-1);
    48     return 0;
    49 }  
    View Code

    作者:ACRykl —— O ever youthful,O ever weeping!

    出处:http://www.cnblogs.com/ACRykl/

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    Class类
    HTML表单格式化
    HTML表单组件
    html常用标签
    Html概述
    Myeclipse2016安装Aptana
    长元音
    对比法记音标
    Java基础八--构造函数
    WPS2012交叉引用技巧,word比wps这点强更新參考文献
  • 原文地址:https://www.cnblogs.com/ACRykl/p/8068102.html
Copyright © 2020-2023  润新知