zoukankan      html  css  js  c++  java
  • JSOI2008——星球大战

    题目:https://www.luogu.org/problemnew/show/1197

    并查集。

    难点是若依次去掉点在求连通块个数,时间太长。

    精妙的思维:先全部读入,再逆向求连通块个数——增加点比删去点对于求个数更容易!

    小技巧:求个数时可以先设个数s为n,每次合并一个fa[ ]就s - -;但此题中别忘了增加点时要s++,且一开始s不是n而是n-w。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,m,x,y,xnt,nex[400005],fa[400005],w,de[400005],cnt,s,c[400005];
    bool bb[400005];
    struct Node{
        int next,to;
    }edge[400005];
    void add(int a,int b)
    {
        xnt++;
        edge[xnt].next=nex[a];
        edge[xnt].to=b;
        nex[a]=xnt;
    }
    int find(int a)
    {
        if(fa[a]==a)return a;
        return fa[a]=find(fa[a]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
            fa[i]=i;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            add(x,y);add(y,x);
        }
        scanf("%d",&w);
        s=n-w;
        for(int i=1;i<=w;i++)
        {
            scanf("%d",&x);
            de[++cnt]=x;
            bb[x]=1;
        }
        for(int i=0;i<n;i++)
            if(!bb[i])
            {
                int u=find(i);
                for(int j=nex[i];j;j=edge[j].next)
                {
                    int k=edge[j].to;
                    if(bb[k])continue;
                    int v=find(k);
                    if(u!=v)
                    {
                        fa[v]=u;
                        s--;
                    }
                }
            }
        c[cnt+1]=s;
        for(int i=cnt;i;i--)
        {
            s++;
            int k=de[i];
            bb[k]=0;
            int u=find(k);
            for(int j=nex[k];j;j=edge[j].next)
            {
                int r=edge[j].to;
                if(bb[r])continue;
                int v=find(r);
                if(u!=v)
                {
                    fa[v]=u;
                    s--;
                }
            }
            c[i]=s;
        }
        for(int i=1;i<=w+1;i++)
            printf("%d
    ",c[i]);
        return 0;
    }
  • 相关阅读:
    C++ 实现简单快速排序
    LEETCODE 198. House Robber
    leetcode 174
    GIT 版本的回退
    unorderd_map 自定义键值及哈希函数的重载
    互斥锁 形成死锁实例
    leetcode 300
    LeetCode 62
    LeetCode 122
    SVN提交,强制注释
  • 原文地址:https://www.cnblogs.com/Narh/p/8276718.html
Copyright © 2011-2022 走看看