【JZOJ3875】星球联盟(alliance)
2017-01-19 21:28
369 查看
Description
在遥远的S星系中一共有N个星球,编号为1…N。其中的一些星球决定组成联盟,以方便相互间的交流。但是,组成联盟的首要条件就是交通条件。初始时,在这N个星球间有M条太空隧道。每条太空隧道连接两个星球,使得它们能够相互到达。若两个星球属于同一个联盟,则必须存在一条环形线路经过这两个星球,即两个星球间存在两条没有公共隧道的路径。
为了壮大联盟的队伍,这些星球将建设P条新的太空隧道。这P条新隧道将按顺序依次建成。一条新轨道建成后,可能会使一些星球属于同一个联盟。你的任务是计算出,在一条新隧道建设完毕后,判断这条新轨道连接的两个星球是否属于同一个联盟,如果属于同一个联盟就计算出这个联盟中有多少个星球。
Solution
两个星球同属于一个联盟,等于它们之间本来有树边相连,然后再给它们直接或间接连上一条边。于是这题我们将初始边和询问边的树边加进去构成树或森林,对于询问的边是树边的就输出No。这个可以用Tarjan缩环或者用并查集实现。
对于这棵树(或森林),我们求出深度,然后对于每个非树边,加入它相当于边的两个端点之间路径的所有点都能属于一个联盟。于是并查集缩点即可。
那么对于一条边的查询,就是查询两个端点所在并查集的大小。
Code
#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #define fo(i,j,k) for(int i=j;i<=k;i++) #define fd(i,j,k) for(int i=j;i>=k;i--) #define rep(i,x) for(int i=ls[x];i;i=nx[i]) #define N 200010 #define M 400010 using namespace std; int to[M],nx[M],ls ,num=0; struct node{ int x,y; bool tr; }b[N*2]; int tot=0; int f ,d ,sz ,fa ; bool bz ; void link(int x,int y) { num++; to[num]=y; nx[num]=ls[x]; ls[x]=num; } int find(int x){ return f[x]==x?x:f[x]=find(f[x]); } int dl ; void bfs(int s) { bz[s]=true; int l=0,r=1; dl[1]=s; while(l<r) { l++; int x=dl[l]; rep(i,x) { int v=to[i]; if(bz[v]) continue; bz[v]=true; d[v]=d[x]+1; fa[v]=x; dl[++r]=v; } } } int lca(int u,int v) { u=find(u),v=find(v); if(u==v) return u; if(d[u]<d[v]) swap(u,v); int t=lca(fa[u],v); f[u]=t; sz[t]+=sz[u]; } int main() { freopen("alliance.in","r",stdin); freopen("alliance.out","w",stdout); int n,m,p; scanf("%d %d %d",&n,&m,&p); fo(i,1,n) sz[i]=1,f[i]=i; fo(i,1,m+p) { int x,y; scanf("%d %d",&x,&y); b[i].x=x,b[i].y=y; int fx=find(x),fy=find(y); if(fx!=fy) { f[fy]=fx; b[i].tr=true; link(x,y); link(y,x); } } fo(i,1,n) if(!bz[i]) d[i]=1,bfs(i); memset(f,0,sizeof(f)); fo(i,1,n) f[i]=i; fo(i,1,m) if(!b[i].tr) lca(b[i].x,b[i].y); fo(i,m+1,m+p) { int x=b[i].x,y=b[i].y; if(b[i].tr) printf("No\n"); else printf("%d\n",sz[lca(x,y)]); } }
相关文章推荐
- 【JZOJ3875】【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- JZOJ 3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- [jzoj]3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)(图论题,构树+缩点+LCA+并查集)
- 【JZOJ3875】【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- 【JZOJ 3875】星球联盟
- 【jzoj3875】【星球联盟】【树】【并查集】
- 【JZOJ 3875】 星球联盟
- 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- bzoj4998 星球联盟(lct+并查集)
- 【NOIP2017练习&BZOJ4998】星球联盟(强联通分量,并查集)
- [BZOJbegin][NOIP十连测热身赛]星球联盟(并查集)
- 【BZOJ4998】星球联盟 LCT+并查集
- 【bzoj 入门OJ】[NOIP 热身赛]Problem C: 星球联盟(并查集)
- 4998: 星球联盟 LCT+并查集
- 开放设计联盟介绍 ODA (Open Design Alliance) Introduction
- Problem C: 星球联盟(并查集+lca)
- bzoj4998 星球联盟
- 星球联盟
- bzoj4998 星球联盟
- 【JZOJ 5451】【NOIP2017提高A组冲刺11.4】Genocide