【并查集】之L2-010 排座位 (25分)详解

1和2是朋友,2和3是朋友。1和3之间就连通了,题目说朋友的朋友也是朋友,所以1和3也是朋友。我们用数组a[]表示下标对应的下一个点多少。例如图  a[1]=2,a[2]=3,     每个点都有自己的下一个点。当下一个点没有了,找不到了,他就是最后一个点,所有的点只要能找到最后这个点的都是朋友
例如现在加进来一个5,5和3是朋友。a[5]=3,虽然a[1]=2,一直找到尽头:a[1]=a[2]=3;所以5和1也是朋友

4和6建立的朋友关系,如果5和6也是朋友关系,那么find(5),find(6),发现find(5)=3,find(6)=4,那么3和4建立了朋友关系,即a[3]=3或者a[4]=3

还有一篇也是并查集的解释:

https://blog.csdn.net/weixin_43535668/article/details/104413573

#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
using namespace std;
int a[200] = { 0 };
int fz[200][200] = { 0 };
//并查集的Find和Merge函数
int Find(int x)
{
	int r = x;
	if (a[r] == 0)
		return r;
	else
	{
		r = Find(a[r]);//递归不断往上面找
	}
	return r;
}
void Merge(int n, int m)
{
	int x = Find(n);
	int y = Find(m);
	if (x != y)
	{
		a[x] = y;
	}
}
int main()
{
	int n, m, k;
	cin >> n >> m >> k;
	for (int i = 0; i < m; i++)
	{
		int q, w, e;
		cin >> q >> w >> e;//宾客1 宾客2 关系
		if (e == 1)//是朋友
		{
			Merge(q, w);//由于朋友的朋友还是朋友,所以要用并查集
		}
		else//是敌人
		{
			fz[q][w] = 1;
			fz[w][q] = 1;

		}
	}
	for (int i = 0; i < k; i++)
	{
		int q, w;
		cin >> q >> w;
		if (Find(q) == Find(w) && fz[q][w]!=1)
			cout << "No problem" << endl;
		else if (Find(q) == Find(w) && fz[q][w] == 1)
			cout << "OK but..." << endl;
		else if (Find(q) != Find(w) && fz[q][w] == 0)
			cout << "OK" << endl;
		else if (fz[q][w] == 1 && Find(q) != Find(w))
			cout << "No way" << endl;
	}

	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43535668/article/details/104436391
今日推荐