L2-024 部落 详细哦!!! 并查集

题解

用并查集
一开始把每个部落的第一人当作头头
在输入的时候
如果B部落发现 人a已经有头头A了 就让人a的头头A 的头头变为B
也就是 a->A->B
但如果a就是B的话 让a的头头是a 即他本身(否者会死循环 a的是A A的是a)

更新一下(新的在下面)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//dp里放的是每个人的祖先
vector<int> dp(10005);
int find(int x)
{
    return dp[x] == x ? dp[x] : dp[x] = find(dp[x]);
}
int main()
{
    int n;
    cin >> n;
    //一开始都弄成-1
    fill(dp.begin(), dp.end(), -1);
    int ans = n, ren = 0;
    //让 部落的第一个人是 主子
    int f;
    int m;
    for (int i = 1; i <= n; ++i)
    {
        cin >> m;
        for (int p = 0; p < m; p++)
        {
            int x;
            cin >> x;
            if (p == 0)
                f = x;
            //之前有
            if (dp[x] != -1)
            {
                //部落数
                ans--;
                //找出x原来的主子
                int t = find(x);
                //让x的主子 成为f的下属
                dp[t] = f;
                if (x == f)
                {
                    dp[x] = x;
                }
            }
            else
            {
                //人数加
                ren++;
                dp[x] = f;
            }
        }
    }
    cout << ren << " " << ans << endl;
    cin >> m;
    while (m--)
    {
        int a, b;
        cin >> a >> b;
        if (find(a) == find(b))
        {
            cout << "Y" << endl;
        }
        else
            cout << "N" << endl;
    }
    return 0;
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <numeric>
#include <set>
using namespace std;
//存祖先
vector<int> dp(10005);
//部落数
int cnt = 0;
//查
int find(int x)
{
	return dp[x] == x ? x : dp[x] = find(dp[x]);
}
//并
void unite(int x, int y)
{
	x = find(x);
	y = find(y);
	if (x == y)
		return;
	--cnt;
	dp[x] = y;
}
int main()
{
	//默认祖先
	iota(dp.begin(), dp.end(), 0);
	//方便找一共多少人
	set<int> people;
	int N;
	cin >> N;
	while (N--)
	{
		int k, a;
		//先把第一个人a 记录一下
		//接下来通过人a 来把大家串起来
		cin >> k >> a;
		people.insert(a);
		while (--k)
		{
			int x;
			cin >> x;
			people.insert(x);
			//并
			unite(a, x);
		}
	}
	//—————————总人数-并起来的数量 就是没并在一起的人是数量 也就是部落数了
	cout << people.size() << ' ' << people.size() + cnt << endl;
	int Q;
	cin >> Q;
	while (Q--)
	{
		int x, y;
		cin >> x >> y;
		cout << ((find(x) == find(y)) ? "Y\n" : "N\n");
	}
	return 0;
}
发布了106 篇原创文章 · 获赞 25 · 访问量 7241

猜你喜欢

转载自blog.csdn.net/weixin_45653525/article/details/104147344