__代码在线求条

P1197 [JSOI2008] 星球大战

EtHereal_Algorithm @ 2023-01-18 16:28:59

#include <bits/stdc++.h>
#define int long long
const int N = 400005;
int fa[N], cnt = 0;
void init(int n) {
    for(int i = 1; i <= n; i++) fa[i] = i;
} // the initial situation
int find(int x) {
    if(fa[x] == x) return x;
    return fa[x] = find(fa[x]);
} // get root(x)
bool check(int x, int y) {
    int fx = find(x), fy = find(y);
    return fx == fy;
} // query
void merge(int x, int y) {
    if(check(x, y)) return ;
    cnt--;
    fa[find(x)] = find(y);
} // merge and make edge

int u[N], v[N], q[N];
bool ok[N];

using namespace std;

vector<int> G[N];

signed main() {
    int n, m;
    cin >> n >> m;
    init(n);
    cnt = n;
    for(int i = 1; i <= m; i++) {
        cin >> u[i] >> v[i];
        u[i]++, v[i]++;
        G[u[i]].push_back(v[i]);
        G[v[i]].push_back(u[i]);
    }
    int k;
    cin >> k;
    for(int i = 1; i <= k; i++) cin >> q[i], q[i]++, ok[q[i]] = 1;
    for(int i = 1; i <= m; i++) {
        if(ok[i]) continue;
        for(auto x : G[i]) {
            if(ok[x]) continue;
            merge(x, i);
        }
    }
    stack<int> ans;
    for(int i = k; i; i--) {
        ans.push(cnt - i);
        int x = q[i];
        ok[x] = 0;
        for(auto y : G[x]) {
            if(ok[y]) continue;
            merge(y, x);
        }
    }
    cout << cnt << endl;
    while(!ans.empty()) {
        cout << ans.top() << endl;
        ans.pop();
    }
    return 0;
}

WA on #9.

目测是没把所有边都 merge 一遍,但是我觉得逻辑上是都 merge 的啊。


by EtHereal_Algorithm @ 2023-01-18 17:17:14

破案了,n,m 写反。此贴完结。

顺便留给后人用。


|