zoukankan      html  css  js  c++  java
  • hdu1213

    hdu1213

    ​                                                             How Many Tables

    0x00 Tags

    并查集(Disjoint Set)

    0x01 题目简介

    有n个人一起吃饭,有些人互相认识。认识的人想坐在一起,不想跟陌生人坐。例如A认识B,B认识C,那么A,B,C会坐在一张桌子上。

    给出认识的人,问需要多少张桌子?

    0x02 代码

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 1010;
    
    int root[maxn];
    
    
    void Init()
    {
    	for (int i = 1; i < maxn; i++)
    	{
    		root[i] = i;
    	}
    }
    
    
    int Find(int x)
    {
    	return x == root[x] ? x : Find(root[x]);
    }
    
    
    void Union(int x, int y)
    {
    	x = Find(x);
    	y = Find(y);
    
    	if (x != y) root[x] = y;
    }
    
    
    
    int main()
    {
    
    	int t, n, m, x, y;
    
    	scanf("%d", &t);
    
    	while (t--)
    	{
    		scanf("%d%d", &n, &m);
    
    		Init();
    
    		for (int i = 1; i <= m; i++)
    		{
    			scanf("%d%d", &x, &y);
    			Union(x, y);
    		}
    
    		int ans = 0;
    
    		for (int i = 1; i <= n; i++)
    		{
    			if (root[i] == i)
    				ans++;
    		}
    
    		printf("%d", ans);
    	}
    
    
    
    	return 0;
    }
    

    0x03 代码优化

    路径压缩

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 1010;
    
    int root[maxn];
    
    
    void Init()
    {
    	for (int i = 1; i < maxn; i++)
    	{
    		root[i] = i;
    	}
    }
    
    // 查找的优化---路径压缩
    int Find(int x)
    {
    	//return x == root[x] ? x : Find(root[x]);
    
    	int r = x;
    
    	while (root[r] != r)
    	{
    		r = root[r];  // 找到根结点
    	}
    
    	int i = x, j;
    	
    	while (i != r)
    	{
    		j = root[i];  // 用临时变量j记录
    		root[i] = r;  // 把路径上元素的集改为根结点
    		i = j;
    	}
    
    	return r;
    }
    
    
    void Union(int x, int y)
    {
    	x = Find(x);
    	y = Find(y);
    
    	if (x != y) root[x] = y;
    }
    
    
    
    int main()
    {
    
    	int t, n, m, x, y;
    
    	scanf("%d", &t);
    
    	while (t--)
    	{
    		scanf("%d%d", &n, &m);
    
    		Init();
    
    		for (int i = 1; i <= m; i++)
    		{
    			scanf("%d%d", &x, &y);
    			Union(x, y);
    		}
    
    		int ans = 0;
    
    		for (int i = 1; i <= n; i++)
    		{
    			if (root[i] == i)
    				ans++;
    		}
    
    		printf("%d", ans);
    	}
    
    
    
    	return 0;
    }
    

    按秩优化

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 1010;
    
    int root[maxn];
    int Rank[maxn];
    
    
    void Init()
    {
    	for (int i = 1; i < maxn; i++)
    	{
    		root[i] = i;
    		Rank[i] = 0;  // 树的高度
    	}
    }
    
    
    int Find(int x)
    {
    	return x == root[x] ? x : Find(root[x]);
    
    }
    
    
    void Union(int x, int y)
    {
    	x = Find(x);
    	y = Find(y);
    
    	if (Rank[x] == Rank[y])
    	{
    		Rank[x] = Rank[x] + 1;
    		root[y] = x;
    	}
    	else
    	{
    		if (Rank[x] < Rank[y]) root[x] = y;
    		else root[y] = x;
    	}
    }
    
    
    
    int main()
    {
    
    	int t, n, m, x, y;
    
    	scanf("%d", &t);
    
    	while (t--)
    	{
    		scanf("%d%d", &n, &m);
    
    		Init();
    
    		for (int i = 1; i <= m; i++)
    		{
    			scanf("%d%d", &x, &y);
    			Union(x, y);
    		}
    
    		int ans = 0;
    
    		for (int i = 1; i <= n; i++)
    		{
    			if (root[i] == i)
    				ans++;
    		}
    
    		printf("%d", ans);
    	}
    
    
    	return 0;
    }
    

    备注

  • 相关阅读:
    jenkins 自动化打包flutter android apk
    k8s 玩转 jenkins
    ceph rbd 找回 pvc
    mysql学习教程之mysql管理
    php链接mysql,php链接mysql的常用方法
    mysql从零开始之MySQL 教程
    mysql从零开始之MySQL 安装
    MySQL8.0.20下载与安装详细图文教程,mysql安装教程
    MySQL8.0.20安装教程,MySQL8.0.20安装详细图文教程
    windwos10安装mysql8.0.20详细图文教程
  • 原文地址:https://www.cnblogs.com/LQ6H/p/12940542.html
Copyright © 2011-2022 走看看