abc304E 加一条边后是否仍为好图
题面:给一张n个点m条边的无向图,另外给出k组约束条件(x[i],y[i]),要求点x[i]不能与y[i]连通,满足全部k组条件的图称为好图。原图为好图,现在给出q组独立的询问,每组询问给定(u,v),问如果在u和v之间加一条边,是否为好图?
范围:n,m,k,q<=2e5
思路:先把图读进来,得到一些连通块,然后将约束条件用set存起来,在处理询问时,检查u,v所在连通块是否会违反约束即可。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a; i<=b; i++)
#define per(i,a,b) for(int i=b; i>=a; i--)
const int N = 200005;
int n, m, k, q, fa[N];
set<pair<int,int>> conflict;
int leader(int x) {
return x == fa[x] ? x : fa[x] = leader(fa[x]);
}
void join(int x, int y) {
x = leader(x);
y = leader(y);
if (x != y) {
fa[x] = y;
}
}
void solve() {
cin >> n >> m;
rep(i,1,n) fa[i] = i;
rep(i,1,m) {
int x, y;
cin >> x >> y;
join(x, y);
}
cin >> k;
while (k--) {
int x, y;
cin >> x >> y;
x = leader(x);
y = leader(y);
if (x > y) swap(x, y);
conflict.insert({x, y});
}
cin >> q;
while (q--) {
int x, y;
cin >> x >> y;
x = leader(x);
y = leader(y);
if (x > y) swap(x, y);
if (conflict.count({x, y}))
cout << "No\n";
else
cout << "Yes\n";
}
}
signed main() {
cin.tie(0)->sync_with_stdio(0);
int t = 1;
while (t--) solve();
return 0;
}