题目链接:传送门(没买的看不了)
并查集维护联通性
对每个点开一个维护不能到达的点
如果两个点联通即那么就直接输出
因为这两个点既然已经在并查集中那就是可以联通的,这条边可以加入
否则需要合并两个,这里要用到启发式合并
将小的集合合并到大的集合上
遍历那个小的集合,如果这个集合中有和另一个点在同一个联通块中的
那就不能连这条边,输出,因为一个点的
中存的是不能联通的元素
如果能连这条边,输出,把小集合的元素插到大集合中,并更新并查集中的
#include <bits/stdc++.h>
#define
using namespace std;
int n, m, q, a, b, fa[A];
set<int> s[A];
int find(int x) {return fa[x] == x ? x : fa[x] = find(fa[x]);}
int main(int argc, char const *argv[]) {
cin >> n >> m >> q;
for (int i = 1; i <= m; i++) {
scanf("%d%d", &a, &b);
s[a].insert(b); s[b].insert(a);
}
for (int i = 1; i <= n; i++) fa[i] = i;
while (q--) {
scanf("%d%d", &a, &b);
int fx = find(a), fy = find(b);
if (fx == fy) {putchar('1'); continue;}
if (s[fx].size() < s[fy].size()) swap(fx, fy);
bool ok = 1;
for (auto v : s[fy]) if (find(v) == fx) {ok = 0; break;}
printf("%d", ok);
if (!ok) continue;
fa[fy] = fx;
for (auto v : s[fy]) s[fx].insert(v);
}
return 0;
}