题目链接

链接

题目大意

n个点,m条路径,d次询问,每次锁定一个点c,给出q条边,问,q条边在锁定c点后多少条边无法连通

题解

并查集支持加一些点进去来判断是不是在一个集合,但是如果删去一个点就不知道多少个点会受影响,所以,这道题的精华就是倒过来,先将那些从来没有锁定的点构建并查集,然后倒过来处理,每次释放一个点,并查集维护没有锁定点的集合。

代码

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#define x first
#define y second
#define endl '\n'
#define IOS                       \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);                   \
    cout.tie(0);

using namespace std;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

const int INF = 0x3f3f3f3f, mod = 1000000007;
const int N = 2e5 + 10;

int n, m, d;
int day[N], p[N];
vector<int> a[N];
vector<pii> v[N];
map<int, int> vis;

int find(int x)
{
    if (x != p[x])
        p[x] = find(p[x]);
    return p[x];
}

void solve()
{
    cin >> n >> m >> d;
    for (int i = 1; i <= n; i++) {
        p[i] = i;
    }
    for (int i = 1; i <= m; i++) {
        int x, y;
        cin >> x >> y;
        a[x].push_back(y);
        a[y].push_back(x);
    }
    for (int i = 1; i <= d; i++) {
        int c, q;
        cin >> c >> q;
        day[i] = c;
        vis[c] = 1;
        while (q--) {
            int x, y;
            cin >> x >> y;
            v[i].push_back({x, y});
        }
    }

    for(int i = 1; i <= n; i++){
        if(vis[i]) continue;
        for(auto x : a[i]){
            if(vis[x]) continue;
            int fx = find(x), fy = find(i);
            if(fx != fy) p[fx] = fy;
        }
    }

    stack<int> q;
    for (int i = d; i; i--) {
        int cnt = 0, c = day[i];
        for(auto x : v[i]){
            int fx = find(x.x), fy = find(x.y);
            if(fx != fy) cnt++;
        }
        q.push(cnt);

        for(auto x : a[c]){
            if(vis[x]) continue;
            int fx = find(x), fy = find(c);
            if(fx != fy) p[fx] = fy;
        }
        vis[c] = 0;

    }
    while (q.size()) {
        cout << q.top() << endl;
        q.pop();
    }
}
int main()
{
    // IOS;
    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}
最后修改:2023 年 07 月 12 日
如果觉得我的文章对你有用,请随意赞赏