BNU - 4216 - 修路 (并查集判断连通分量)

修路

Time Limit: 1000ms
Memory Limit: 65536KB
64-bit integer IO format:  %lld      Java class name:  Main
Type: 
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •                   
  •  在某个景区内有n个景点,它们之间有m条路相连。然而,这m条路可能是不足够的,因为无法把这n个景点都连通起来。

    例如当m<n-1的时候,就必定有部分景点被孤立。
    所以,现在政府想修建道路,想把这些景点都连通起来。问题是,在现在的基础上,最少要再修建多少条道路呢?
     

    Input

     第一行是n,m (1<=n<=1e5,1<=m<=1e6)

    接下来就是m行,每行两个1 ~ n范围内的数,表示编号为这两个数的景点之间有一道路相连

    Output

     输出最少要再修建的道路的条数

    Sample Input

    5 2
    1 2
    3 4

    Sample Output

    2

    Source





    思路:就是去寻找连通分量的个数cnt,最少修建的道路个数即为cnt-1(犯了两超傻逼错误╮(╯_╰)╭)


    AC代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream> 
    using namespace std;
    
    const int maxn = 100005;
    int pa[maxn], vis[maxn];
    
    int find(int x) {
    	return pa[x] != x ? pa[x] = find(pa[x]) : x;
    }
    
    int main() {
    	int n, m;
    	while(scanf("%d %d", &n, &m) != EOF) {
    		for(int i = 0; i <= n; i++) pa[i] = i; 
    		memset(vis, 0, sizeof(vis));
    		while(m--) {
    			int a, b;
    			scanf("%d %d", &a, &b);
    			a = find(a), b = find(b);
    			if(a != b) pa[a] = b;
    		}
    		
    		int cnt = 0;
    		for(int i = 1; i <= n; i++) {
    			int tmp = find(i);
    			if(!vis[tmp]) {
    				vis[tmp] = 1;
    				cnt++;
    			}
    		}
    		
    		printf("%d\n", cnt-1);
    	}
    	return 0;
    }









    • 1
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值