40分求救

P1197 [JSOI2008] 星球大战

molarsu @ 2021-12-27 20:39:11

#include<iostream>
#include<stack>
#include<map>
#include<set>
using namespace std;
const int maxn = 400005;
int n, m, a[maxn], b[maxn], k, usa[maxn], x[maxn], pre[maxn],cnt, head[maxn], ecnt, ans[maxn];
stack<int> destory;
int fd(int y) {
    if (pre[y] == y) return y;
    return y = fd(pre[y]);
}
void hb(int aa, int bb) {
    aa = fd(aa), bb = fd(bb);
    pre[bb] = aa;
}
struct edge {
    int x, nxt;
}e[maxn << 1];
void add_edge(int u, int v) {
    ecnt++;
    e[ecnt].nxt = head[u];
    e[ecnt].x = v;
    head[u] = ecnt;
}
int cntt(int xx) {
    set<int> s;
    for (int i = head[xx]; i; i = e[i].nxt) {
        int u = e[i].x;
        if (!usa[u]) {
            s.insert(fd(u));
        }
    }
    return s.size();
}
int main() {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= m; i++)scanf("%d %d", &a[i], &b[i]),add_edge(a[i],b[i]),add_edge(b[i],a[i]);
    for (int j = 0; j < n; j++) {
        pre[j] = j;
    }
    scanf("%d", &k);
    for (int i = 1; i <= k; i++) {
        scanf("%d", &x[i]);
        usa[x[i]] = true;
    }
    for (int i = 0; i < n; i++) {
        if (!usa[a[i]] && !usa[b[i]]) {
            hb(a[i], b[i]);
        }
    }
    for (int i = 0; i < n; i++) {
        if (!usa[i] && fd(i) == i)cnt++;
    }
    ans[k + 1] = cnt;
    for (int j = k; j >= 1; j--) {
        int tmp = x[j];
        usa[tmp] = false;
        bool f = false;
        int cnt1 = cntt(tmp);
        for (int i = head[tmp]; i; i = e[i].nxt) {
            int u = e[i].x;
            int tmpp = fd(u);
            if (!usa[u]) {
                hb(u, tmp);
                f = true;
            }
            if (fd(u) != tmpp)cnt--;
        }
        if (!f)cnt++;
        else cnt -= cnt1, cnt++;
        ans[j] = cnt;
    }
    for (int i = 1; i <= k + 1; i++)cout << ans[i] << endl;
    return 0;
}

反向加边的思路, 一直是40分 第五个点还没输出 求救


by molarsu @ 2021-12-27 20:40:35

评测链接


by molarsu @ 2021-12-28 09:02:59

发现两个问题,head没初始化,编号有零没注意,使用了直接判断i的真假


by molarsu @ 2021-12-31 10:44:28

此贴终,出现的问题首先是并查集优化写错了, 第二个是 有一个for 循环的条件写错了


|