• 星球大战 并查集!!!


    Sample Input

    8 13 0 1 1 6 6 5 5 0 0 6 1 2 2 3 3 4 4 5 7 1 7 2 7 6 3 6 5 1 6 3 5

    Sample Output

    1 1 1 2 3 3

    #include <bits/stdc++.h>
    using namespace std;
    
    int tot,n,m,d,f[400001],head[400001],q[400001],ans[400001],cnt=1;
    
    bool used[400001], des[400001];
    struct data{int to,next;}e[400001]; //next是
    
    int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
    
    void ins(int u,int v) {//存图
        e[++cnt].to=u; e[cnt].next=head[v]; head[v]=cnt;
        e[++cnt].to=v; e[cnt].next=head[u]; head[u]=cnt;
    }
    
    void add(int x) {
        int i=head[x],p=find(x),q; //p是x的父节点,
        while(i) {
            if(used[e[i].to]) { // 如果该点被使用过
                q=find(e[i].to); //q就为e[i].to的父节点
                if(p!=q){f[q]=p;tot--;} //如果两个父节点不同(不是它本身) p为q的父节点 tot自减
            }
            i=e[i].next; //i为与它相邻的点
        } 
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++) f[i]=i;
    
        for(int i=1;i<=m;i++) {
            int x,y;
            scanf("%d%d",&x,&y);
            ins(x,y);
        }
    
        scanf("%d",&d); // d是进行的操作次数
        for(int i=1;i<=d;i++) {
            scanf("%d",&q[i]);
            des[q[i]]=1; // 记录被摧毁的星球
        }
    
        for(int i=0;i<n;i++) {
            if(!des[i]) { //如果该星球没有被摧毁
                tot++;  //记录没有被摧毁的星球个数
                add(i); //传入add函数(即merge函数进行并查集构图
                used[i]=1; //i已经进入图中
            }
        }
        ans[d+1]=tot;  //此时tot是除去被摧毁星球的连通块数目
    
        for(int i=d;i>0;i--) {
            tot++; // 摧毁一个星球首先默认会导致连通块++
            add(q[i]); //将被摧毁的星球补回去
            used[q[i]]=1; //q[i]被使用 
            ans[i]=tot;  // tot此时为该状态下的连通块数
        }
    
        for(int i=1;i<=d+1;i++)printf("%d
    ",ans[i]);
        return 0;
    }
    
    作者:LightAc
    出处:https://www.cnblogs.com/lightac/
    联系:
    Email: dzz@stu.ouc.edu.cn
    QQ: 1171613053
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。
  • 相关阅读:
    产品经理之PRD详解(非原创)
    编写代码的「八荣八耻」- 以开关上线为荣,以自信编码为耻
    安装社区版git仓库
    【干货分享】大话团队的GIT分支策略进化史
    Android IPC机制(一)开启多进程
    使用adb命令通过IP地址连接手机
    一篇文章了解Github和Git教程-AndroidStudio上传Github教程
    sublime实现markdown浏览器预览
    idea上maven使用心得(三)——用pom.xml添加jar包
    idea解决Maven jar依赖冲突(四)
  • 原文地址:https://www.cnblogs.com/lightac/p/10721378.html
Copyright © 2020-2023  润新知