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