其他分享
首页 > 其他分享> > [LuoguP1197][JSOI2008]星球大战

[LuoguP1197][JSOI2008]星球大战

作者:互联网

题目意思很容易理解。

给定一个无向图,有\(k\)次操作,每次破坏一个点,输出每次操作后的联通块个数。

题解

一想到连通性,我们会情不自禁想到\(\text{并查集}\)。

\(\text{What!?}\)删点?并查集好像不支持诶。。。

但是,这题就是并查集!!!

但是思路需要小小转变一下——

\[\text{逆向思维!}\]

谁说是强制在线的?

我们不妨先把图破坏成最终形态,再_将操作逆序进行_。

具体实现:

在上述的并查集合并中,如果一开始两点不在通一个连通块中,那么将\(count--\)。

\[\text{MainCodeHere}\]

#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;

const int MAX_N=1e6+10;
int uset[MAX_N];
vector<int> G[MAX_N];
bool broken[MAX_N];
int opts[MAX_N];
int ans[MAX_N];
int n,m,k;
int count;

int find(int x){
    return (x==uset[x])?x:uset[x]=find(uset[x]);
    //常规的并查集查找。 
}
inline void merge(int x,int y){
    int fx=find(x),fy=find(y);
    if(fx==fy)return;//如果本来就是同一个,忽略。
    count--;uset[fx]=fy;
    //不在同一个连通块,合并之后家记得将count--! 
}

int main()
{
    register int i,j;
    scanf("%d%d",&n,&m);
    memset(broken,0,sizeof(broken));
    for(i=0;i<n;i++)uset[i]=i;
    for(i=1;i<=m;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        G[u].push_back(v) ;
        G[v].push_back(u) ;
        //建立原始图 
    }
    scanf("%d",&k);
    count=n-k;//最初并查集的连通块个数。 
    for(i=1;i<=k;i++)
        scanf("%d",&opts[i]),broken[opts[i]]=1;//记录最终会被破坏的点。 
    for(i=0;i<n;i++)
    {
        if(broken[i])continue;
        for(j=0;j<G[i].size() ;j++)
        {
            if(broken[G[i][j]])continue;
            merge(i,G[i][j]);
        }
        //在并查集上初始化永久完好的信息。 
    }//O(m*UFS) 
    for(i=k;i>=1;i--)//逆序 
    {
        ans[i]=count++;
        //记录答案,注意加点时连通块要先+1(毕竟多了一个点)。 
        broken[opts[i]]=0;//现在它就不是损坏了的了。 
        for(j=0;j<G[opts[i]].size() ;j++)
            if(!broken[G[opts[i]][j]])//注意不要将此时还没有加入的点合并如并查集。 
                merge(opts[i],G[opts[i]][j]);
    }//O(k*x*UFS)
    ans[0]=count;
    //注意题目还要求记录完好时连通块的个数。 
    for(i=0;i<=k;i++)//正序输出 
        printf("%d\n",ans[i]);
    return 0;
}

时间复杂度:\(O(n+m+k+m\alpha +kx\alpha)\)

\(\alpha\) 指一次并查集操作的时间,\(x\)指所有被破坏的点的连边数目的平均数。

标签:count,JSOI2008,int,MAX,查集,LuoguP1197,broken,uset,星球大战
来源: https://www.cnblogs.com/-Wallace-/p/10657470.html