求助

P1197 [JSOI2008] 星球大战

qzilr @ 2021-10-17 21:06:19

#include <bits/stdc++.h>

using namespace std;
const int maxn = 5e5;

struct T {
    int fa[maxn];
    T(){
        for (int i = 0; i <= maxn; ++i)
            fa[i] = i;
    }
    inline int find(int o) {
        if (fa[o] == o) return o;
        return fa[o] = find(fa[o]);
    }
    inline void uion(int x, int y) {
        if (find(x) != find(y))
            fa[find(x)] = find(y);
    }
}t;
struct edge {
    int v, next;
}e[maxn];
int head[maxn], tot = 0, sum = 0, broke[maxn], order[maxn], ans[maxn], vis[maxn];

inline void add(int u, int v) {
    e[++tot] = (edge) {v, head[u]};
    head[u] = tot;
}

int main() {
    ios::sync_with_stdio(false);
    int n, m, k;
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int u, v;
        cin >> u >> v;
        add(u, v), add(v, u);
    }
    cin >> k;
    for (int i = 1; i <= k; ++i) {
        int o;
        cin >> o;
        broke[o] = 1, order[i] = o;
    }
    sum = n - k;
    queue<int> q;
    q.push(0);
    vis[0] = 1;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        if (vis[u]) continue;
        for (int i = head[u]; i; i = e[i].next ) {
            int v = e[i].v ;
            q.push(v);
            vis[v] = 1;
            if (!broke[v] && !broke[u] && t.find(v) != t.find(u) )
                t.uion(v, u), sum--;
        }
    }
    ans[k + 1] = sum;
    for (int i = k; i > 1; --i) {
        int o = order[i];
        sum++;
        for (int l = head[o]; l; l = e[l].next ) {
            int v = e[l].v ;
            if (t.find(v) != t.find(o) )
                t.uion(v, o), sum--; 
        }
        ans[i] = sum;
    }
    for (int i = 2; i <= k + 1; ++i)
        printf("%d\n", ans[i]);
    return 0;
}

|