# bzoj4998: 星球联盟

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  阅读(247)  评论(0编辑  收藏  举报