救救孩子,40分样例已过

P1197 [JSOI2008] 星球大战

iqwl @ 2023-04-02 17:10:23

#include<iostream>
#include<algorithm> 
#include<cstring>
using namespace std;
const int N=4e5+10,M=4e5+10;
int h[N],ne[M],e[M],idx,from[M];
int n,m,k;
int broken[M];
int b[M];
int f[M];
int ans[M],tot=0;
int find(int x){
    return x==f[x]?x:f[x]=find(f[x]);
}
void merge(int a,int b){
    a=find(a),b=find(b);
    if(a!=b)f[a]=b;
}
void add(int a,int b){
    from[idx]=a,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int main(){
    memset(h,-1,sizeof h); 
    cin>>n>>m;
    for(int i=0;i<=n;i++)f[i]=i;
    int x,y;
    for(int i=1;i<=m;i++){
        cin>>x>>y;
        add(x,y);
        add(y,x);
    }
    cin>>k;
    for(int i=1;i<=k;i++){
        cin>>broken[i];
        b[broken[i]]=1;
    }
    tot=n-k;
    for(int i=1;i<=2*m;i++){
        if(!e[i]&&!from[i]&&find(e[i])!=find(from[i])){
            merge(from[i],e[i]);
            tot--;
        }
    }
    ans[k+1]=tot;
    for(int i=k;i>=1;i--){
        tot++;
        b[broken[i]]=0;
        for(int j=h[broken[i]];j!=-1;j=ne[j]){
            int p=e[j];
            if(!b[p]&&find(p)!=find(broken[i])){
                tot--;
                merge(broken[i],p);
            }
        }
        ans[i]=tot;
    }
    for(int i=1;i<=k+1;i++)cout<<ans[i]<<endl;
    return 0;
} 

|