zoukankan      html  css  js  c++  java
  • BZOJ 1015 并查集

    思路:

    考虑时光倒流

    先把没有被删掉的点之间的边加上去

    再从后向前加边

    用并查集判断连通性即可

    //By SiriusRen
    #include <vector>
    #include <cstdio>
    using namespace std;
    #define N 400050
    int n,m,xx,yy,q[N],f[N],ans[N],cnt,k,vis[N];
    vector<int>v[N];
    int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)f[i]=i;
        for(int i=1;i<=m;i++){
            scanf("%d%d",&xx,&yy);
            v[xx].push_back(yy);
            v[yy].push_back(xx);
        }
        cnt=n;
        scanf("%d",&k);
        for(int i=1;i<=k;i++)scanf("%d",&q[i]),vis[q[i]]=1;
        for(int ii=0;ii<n;ii++)if(!vis[ii])
            for(int i=0;i<v[ii].size();i++){
                if(vis[v[ii][i]])continue;
                int fx=find(ii),fy=find(v[ii][i]);
                if(fx!=fy)f[fx]=fy,cnt--;
            }
        ans[k+1]=cnt-k;
        for(int ii=k;ii;ii--){
            vis[q[ii]]=0;
            for(int i=0;i<v[q[ii]].size();i++){
                if(vis[v[q[ii]][i]])continue;
                int fx=find(q[ii]),fy=find(v[q[ii]][i]);
                if(fx!=fy)f[fx]=fy,cnt--;
            }
            ans[ii]=cnt-ii+1;
        }
        for(int i=1;i<=k+1;i++)printf("%d
    ",ans[i]);
    }

    这里写图片描述

  • 相关阅读:
    字符,字符串,字节
    111
    串口通信
    字符编码
    枚举和结构体
    参数数组
    .Net垃圾回收机制
    try{ } catch{ } finally{ }
    LVS 工作原理图文讲解
    自动化运维工具—Ansible常用模块二
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532255.html
Copyright © 2011-2022 走看看