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;
}
posted @ 2024-03-07 21:53  chenfy27  阅读(1)  评论(0编辑  收藏  举报