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;
    }
    

    备注

  • 相关阅读:
    如何使用Orchard搭建敏捷个人的网站(1)
    英语:敏捷英语学习开始了
    英语:普特三步听写法(转载)
    色拉英语第一集第五幕:好胖的一只鸟
    介绍一个基于ASP.NET MVC的框架Catharsis
    色拉英语第2集第3幕:He’s my favorite
    Orchard:如何生成Hello World模块
    如何使用Orchard搭建敏捷个人的网站(2)
    色拉英语第一集第四幕:我不喜欢北京烤鸭
    色拉英语第一集第二幕:请问南京路怎么走?
  • 原文地址:https://www.cnblogs.com/LQ6H/p/12940542.html
Copyright © 2011-2022 走看看