40分,求调

P1197 [JSOI2008] 星球大战

sundyLIUXY @ 2023-02-28 20:02:22

#include <bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x7fffffff;
const int DINF = 1000000000;
const ll LINF = 8000000000000000000;
const int MOD = 1000000007;
const int PRIME = 103;
using namespace std;

int n, m, k, idx, ans;
int h[200010], z[400010], aans[400010], fa[400010];
bool b[400010];
struct EDGE
{
    int to, ne;
} edge[400010];

void add(int fr, int to)
{
    edge[++idx].to = to, edge[idx].ne = h[fr], h[fr] = idx;
}
int find(int u)
{
    if(fa[u] != u) fa[u] = find(fa[u]);
    return fa[u];
}
void merge(int u, int v)
{
    u = find(u), v = find(v);
    if(u != v) fa[u] = v;
}

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) fa[i] = i;
    for(int i = 1; i <= m; i++) 
    {
        int x, y;
        scanf("%d%d", &x, &y), x++, y++;
        add(x, y), add(y, x);
    }
    scanf("%d", &k), ans = n-k;
    for(int i = 1; i <= k; i++) scanf("%d", &z[i]), z[i]++, b[z[i]] = 1;
    for(int i = 1; i <= n; i++)
        if(!b[i])
            for(int j = h[i]; j; j = edge[j].ne)
                if(!b[edge[j].to]) merge(i, edge[j].to), ans--;
    aans[k+1] = ans;
    for(int i = k; i >= 1; i--)
    {
        ans++, b[z[i]] = 0;
        for(int j = h[z[i]]; j; j = edge[j].ne)
            if(!b[edge[j].to] && find(z[i]) != find(edge[j].to))
                merge(z[i], edge[j].to), ans--;
        aans[i] = ans;
    }
    for(int i = 1; i <= k+1; i++) printf("%d\n", aans[i]);

    return 0;
}

|