zoukankan      html  css  js  c++  java
  • P1197 [JSOI2008]星球大战——链式前向星+并查集

    https://www.luogu.org/problem/P1197

    这道题算是关闭农场的加强版吧,数据有点大,矩阵存不下;

    也是记录删点操作,从后往前加边;

    先将每个点都算成一个连通块,然后每连一条边连通块数就减一;

    加一个点时不要忘记连通块数+1,然后合并;

    还有数组要开大;

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=400010;
    int pre[maxn*2],last[maxn],other[maxn*2],from[maxn*2],l;
    int n,m,k;
    int out_block[maxn*2],delete_order[maxn*2];
    int num_block[maxn*2],tot_block;
    int father[maxn*2];
    void add(int x,int y)
    {
        l++;
        from[l]=x;
        pre[l]=last[x];
        last[x]=l;
        other[l]=y;
    }
    
    int getfather(int x)
    {
        if(father[x]==x) return x;
        father[x]=getfather(father[x]);
        return father[x];
    }
    
    void merge(int x,int y)
    {
        int fx=getfather(x);
        int fy=getfather(y);
        father[fx]=fy;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y);add(y,x);
        }
        scanf("%d",&k);
        for(int i=1;i<=k;i++)
        {
            scanf("%d",&delete_order[i]);
            out_block[delete_order[i]]=1;
        }
        tot_block=n-k;
        for(int i=1;i<=n;i++) father[i]=i;
        for(int i=1;i<=m*2;i++)
        {
            if(!out_block[from[i]]&&!out_block[other[i]]&&getfather(from[i])!=getfather(other[i]))
            {
                merge(from[i],other[i]);
                tot_block--;
            }
        }
        num_block[k+1]=tot_block;
        for(int i=k;i>=1;i--)
        {
            out_block[delete_order[i]]=0;
            tot_block++;
            for(int p=last[delete_order[i]];p;p=pre[p])
            {
                int v=other[p];
                if(!out_block[v]&&getfather(delete_order[i])!=getfather(v))
                {
                    tot_block--;
                    merge(delete_order[i],v);
                }
            }
            num_block[i]=tot_block;
        }
        for(int i=1;i<=k+1;i++)
        {
            printf("%d
    ",num_block[i]);
        }
        return 0;
    }
  • 相关阅读:
    mysql常用技能分享
    php生成器使用总结
    MySQL索引使用方法和性能优化
    servlet相关
    UML图
    How Tomcat Works
    字符串编码
    高效工作
    php 设计模式总结
    python之装饰器
  • 原文地址:https://www.cnblogs.com/WHFF521/p/11603164.html
Copyright © 2011-2022 走看看