void init() //初始化
{
for (int i = 1; i <= n; i++)
father[i] = i;
}
int find(int u) //查找
{
if (u != father[u])
father[u] = find(father[u]);
return father[u];
}
bool isSame(int u, int v) //判断两节点是否同一根节点(是否连通)
{
int rootu = find(u);
int rootv = find(v);
return rootu == rootv;
}
void join(int u, int v) //合并
{
int rootu = find(u);
int rootv = find(v);
if (rootu != rootv)
father[rootv] = rootu;
}
// 并查集初始化
void init()
{
for (int i = 1; i <= n; i++) // 注意本题节点是从1到n
father[i] = i; // 初始化每个节点的父节点指向自己
}
查找:
cpp复制代码
// 并查集里寻找该节点的根节点(带路径压缩)
int find(int u)
{
if (u != father[u]) // 如果当前节点不是根节点,就会递归地调用 find 函数来找到根节点,并将沿途的所有节点的父节点设置为根节点
father[u] = find(father[u]); // 路径压缩:将u的父节点设置为u的根节点
return father[u]; // 返回u的根节点
}
合并:
cpp复制代码
// join 函数用于合并两个节点所在的集合:将v->u这条边加入并查集
void join(int u, int v)
{
int rootu = find(u); // u的根节点
int rootv = find(v); // v的根节点
if (rootu != rootv)
father[rootv] = rootu; // 将v-u这条边加入并查集:将节点 v 的根节点(也是 v 所在集合的代表)的父节点设置为 u 的根节点。这样,v 的根节点及其所有子节点(包括 v)现在都属于以 u 的根节点为代表的集合
}
完整代码如下:
cpp复制代码
#include <bits/stdc++.h>
using namespace std;
int n; // 节点数量
vector<int> father = vector<int>(101, 0); // 并查集数据结构:节点编号从1到n,而题目节点个数最大为100 -- 故初始化大小101
// 并查集初始化
void init()
{
for (int i = 1; i <= n; i++) // 注意本题节点是从1到n
father[i] = i; // 初始化每个节点的父节点指向自己
}
// 并查集里寻找该节点的根节点(带路径压缩)
int find(int u)
{
if (u != father[u]) // 如果当前节点不是根节点,就会递归地调用 find 函数来找到根节点,并将沿途的所有节点的父节点设置为根节点
father[u] = find(father[u]); // 路径压缩:将u的父节点设置为u的根节点
return father[u]; // 返回u的根节点
}
// 判断u和v是否找到同一个根节点 -- 是否在同一个集合中
bool isSame(int u, int v)
{
int rootu = find(u);
int rootv = find(v);
return rootu == rootv;
}
// join 函数用于合并两个节点所在的集合:将v->u这条边加入并查集
void join(int u, int v)
{
int rootu = find(u); // u的根节点
int rootv = find(v); // v的根节点
if (rootu != rootv)
father[rootv] = rootu; // 将v-u这条边加入并查集:将节点 v 的根节点(也是 v 所在集合的代表)的父节点设置为 u 的根节点。这样,v 的根节点及其所有子节点(包括 v)现在都属于以 u 的根节点为代表的集合
}
int main()
{
int m, s, t, source, destination;
cin >> n >> m;
init(); // 初始化并查集
while (m--)
{
cin >> s >> t;
join(s, t); // 将s和t所在的集合合并(即将s-t这条边加入并查集)
}
cin >> source >> destination;
if (isSame(source, destination)) // 判断这两个节点是否在同一个集合中(是否连通)-- 有同一个根
cout << 1 << endl;
else
cout << 0 << endl;
}