频道栏目
首页 > 资讯 > 其他 > 正文

【JZOJ 3875】星球联盟

17-01-21        来源:[db:作者]  
收藏   我要投稿

Description

在遥远的S星系中一共有N个星球,编号为1…N。其中的一些星球决定组成联盟,以方便相互间的交流。

但是,组成联盟的首要条件就是交通条件。初始时,在这N个星球间有M条太空隧道。每条太空隧道连接两个星球,使得它们能够相互到达。若两个星球属于同一个联盟,则必须存在一条环形线路经过这两个星球,即两个星球间存在两条没有公共隧道的路径。

为了壮大联盟的队伍,这些星球将建设P条新的太空隧道。这P条新隧道将按顺序依次建成。一条新轨道建成后,可能会使一些星球属于同一个联盟。你的任务是计算出,在一条新隧道建设完毕后,判断这条新轨道连接的两个星球是否属于同一个联盟,如果属于同一个联盟就计算出这个联盟中有多少个星球。

Solution

看到这题,第一反应就是tarjan缩环,

首先,我们必须保证初始图的连通性必须和最后图的连通性相同,

显然,一条把两张不连通的边的答案就是0,所以先把询问中的这种边连上,

缩完环以后,出来的就是一颗dfs树,在这上边做LCA,

对于一个询问,先求LCA,要么是连向他的父亲,要么是横插边,每次把新的环缩起来,边统计答案,

每次做完以后LCA并不需要维护,(读者们可以思考一下)

复杂度:O(nlog(n))

Code

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define efo(i,q) for(int i=A[q];i;i=B[i][0])
using namespace std;
const int N=200500,M=18;
int read(int &n)
{
    char ch=' ';int q=0,w=1;
    for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
    if(ch=='-')w=-1,ch=getchar();
    for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;
}
int m,n,ans,m1,TI;
int B[4*N][3],A[N],B0=1;
int low[N],dfn[N],za[N];
int sum[N],g[N],si[N];
int z[N];
int G[N][M+1],de[N];
int root[N],sc[N][3];
int FA[N];
void link(int q,int w)
{
    B[++B0][0]=A[q];A[q]=B0,B[B0][1]=w,B[B0][2]=0;
    B[++B0][0]=A[w];A[w]=B0,B[B0][1]=q,B[B0][2]=0;
}
void dfsf(int q,int RT)
{
    g[q]=RT;
    efo(i,q)if(!g[B[i][1]])dfsf(B[i][1],RT);
}
int gf(int q){return (g[q]==q)?q:(g[q]=gf(g[q]));}
int tarjan(int q,int c)
{
    za[++za[0]]=q;dfn[q]=low[q]=c;
    si[q]=0;g[q]=q;
    efo(i,q)if(!B[i^1][2])
    {
        B[i][2]=1;
        if(dfn[B[i][1]]<c)
        {
            low[q]=min(low[q],low[B[i][1]]);
        }else low[q]=min(low[q],tarjan(B[i][1],c+1));
    }
    if(low[q]==dfn[q])
    {
        si[q]=1;
        while(za[za[0]]!=q)
        {
            int w=za[za[0]];
            g[w]=q;si[q]++;za[0]--;
        }
        za[0]--;
    }
    return low[q];
}
void dfs(int q,int c,int fa)
{
    G[q][0]=fa;de[q]=c;
    FA[q]=fa;
    efo(i,q)if(B[i][1]!=fa)dfs(B[i][1],c+1,q);
}
int LCA1(int q,int c)
{
    while(de[q]>c)
    {
        int i=0;
        while(de[G[q][i+1]]>=c&&i<M)i++;
        q=G[q][i];
    }
    return q;
}
int LCA(int q,int w)
{
    q=LCA1(q,de[w]);w=LCA1(w,de[q]);
    while(q!=w)
    {
        int i=0;
        while(G[q][i+1]!=G[w][i+1])i++;
        q=G[q][i];w=G[w][i];
    }
    return q;
}
void UP(int q,int w)
{
    while(q!=w)
    {
        g[gf(q)]=gf(w);
        si[w]+=si[q];
        FA[q]=gf(FA[q]);
        q=FA[q];
    }
}
int main()
{
    int q,w,e;
    read(n),read(m),read(m1);
    fo(i,1,m)read(q),read(w),link(q,w);
    fo(i,1,m1)read(sc[i][0]),read(sc[i][1]);
    fo(i,1,n)if(!g[i])dfsf(i,i);
    fo(i,1,m1)if(gf(sc[i][0])!=gf(sc[i][1]))
    {
        g[gf(sc[i][1])]=gf(sc[i][0]);
        link(sc[i][0],sc[i][1]);sc[i][2]=1;
    }
    fo(i,1,n)if(i==gf(g[i]))root[++root[0]]=i;
    memset(dfn,127,sizeof(dfn));
    memset(low,127,sizeof(low));
    fo(i,1,root[0])tarjan(root[i],1);
    fo(i,1,n)
    {
        int j;
        for(j=A[i];B[j][0];j=B[j][0])B[j][1]=g[B[j][1]];
        if(j&&g[i]!=i)
        {
            B[j][1]=g[B[j][1]];
            B[j][0]=A[g[i]];
            A[g[i]]=A[i];A[i]=0;
        }
    }
    fo(i,1,n)
    {
        TI++;
        while(A[i]&&B[A[i]][1]==i)A[i]=B[A[i]][0];
        int j1=A[i];
        z[i]=z[B[j1][1]]=TI;
        for(int j=B[j1][0];j;j=B[j][0])
            if(z[g[B[j][1]]]==TI)
            {
                B[j1][0]=B[j][0];
            }else z[B[j][1]]=TI,j1=j;
    }
    fo(i,1,root[0])dfs(root[i],1,0);
    fo(j,1,M)fo(i,1,n)if(G[i][0])
        G[i][j]=G[G[i][j-1]][j-1];
    fo(i,1,m1)
    {
        if(sc[i][2]){printf("No\n");continue;}
        q=gf(sc[i][0]),w=gf(sc[i][1]);
        e=LCA(q,w);
        q=gf(q);w=gf(w),e=gf(e);
        if(q==w&&q==e){printf("%d\n",si[q]);continue;}
        ans=0;
        UP(q,e);
        UP(w,e);
        printf("%d\n",si[e]);
    }
    return 0;
}
相关TAG标签
上一篇:github pages+hexo搭建博客
下一篇:微信公众号平台的泛泛之谈
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站