bzoj4998: 星球联盟

被gc巨侠D飞来做这题,好恶心,还不让人在线LCT T_T (其实明明就是你忘了强行甩锅)

xgc:并查集乱搞就能过写什么LCT

动态维护双联通分量

我们离线做......

首先做一次最小生成树,构出搜索树

然后没有用到的边就拿去暴力合并环,用并查集跳着找

完了

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

struct node
{
    int x,y,next;
}a[810000];int len,last[210000];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}
int fa[2][210000];
int findfa(int x,int w)
{
    if(fa[w][x]<0)return x;
    fa[w][x]=findfa(fa[w][x],w);return fa[w][x];
}
int dep[210000];
void dfs(int x)
{
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        if(dep[y]==0)
            dep[y]=dep[x]+1, fa[0][y]=x, dfs(y);
    }
}
int Link(int x,int y)
{
    int fx=findfa(x,1),fy=findfa(y,1);
    if(fx!=fy)
    {
        int tot=0; x=fx,y=fy;
        while(x!=y)
        {
            if(dep[x]<dep[y])swap(x,y);
            tot+=fa[1][x];
            fa[1][x]=findfa(fa[0][x],1);
            x=fa[1][x];
        }
        fa[1][x]+=tot;
    }
    return -fa[1][findfa(x,1)];
}

struct edge{int x,y;}e[410000];
bool v[410000];
int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    int n,m,Q,x,y;
    scanf("%d%d%d",&n,&m,&Q);
    
    for(int i=1;i<=n;i++)fa[1][i]=-1;
    len=1;memset(last,0,sizeof(last));
    memset(v,false,sizeof(v));
    for(int i=1;i<=m+Q;i++)
    {
        scanf("%d%d",&e[i].x,&e[i].y);
        int fx=findfa(e[i].x,1),fy=findfa(e[i].y,1);
        if(fx!=fy)
        {
            v[i]=true; fa[1][fx]=fy;
            ins(e[i].x,e[i].y), ins(e[i].y,e[i].x);
        }
    }
    
    memset(dep,0,sizeof(dep));
    for(int i=1;i<=n;i++)
        if(dep[i]==0) dep[i]=1, fa[0][i]=0, dfs(i);
        
    for(int i=1;i<=n;i++)fa[1][i]=-1;
    for(int i=1;i<=m+Q;i++)
    {
        if(v[i]==true)
        {
            if(i>m)printf("No\n");
        }
        else
        {
            int d=Link(e[i].x,e[i].y);
            if(i>m)
            {
                if(d==-1)printf("No\n");
                else printf("%d\n",d);
            }
        }
    }
    return 0;
}

 

posted @ 2018-09-19 11:00  AKCqhzdy  阅读(249)  评论(0编辑  收藏  举报