【jzoj3875】【星球联盟】【树】【并查集】
2017-01-18 21:10
323 查看
题目大意
在遥远的S星系中一共有N个星球,编号为1…N。其中的一些星球决定组成联盟,以方便相互间的交流。但是,组成联盟的首要条件就是交通条件。初始时,在这N个星球间有M条太空隧道。每条太空隧道连接两个星球,使得它们能够相互到达。若两个星球属于同一个联盟,则必须存在一条环形线路经过这两个星球,即两个星球间存在两条没有公共隧道的路径。为了壮大联盟的队伍,这些星球将建设P条新的太空隧道。这P条新隧道将按顺序依次建成。一条新轨道建成后,可能会使一些星球属于同一个联盟。你的任务是计算出,在一条新隧道建设完毕后,判断这条新轨道连接的两个星球是否属于同一个联盟,如果属于同一个联盟就计算出这个联盟中有多少个星球。
解题思路
离线所有询问,将最早出现的边构成树,其他的先存起来,用询问边构成树边的打no的标记。将给出的边构成的环用并查集并起来,暴力并即可,深度大的先并,因为只会并一次,维护集合和点数即可。
code
#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define LF double #define LL long long #define min(a,b) ((a<b)?a:b) #define max(a,b) ((a>b)?a:b) #define fo(i,j,k) for(int i=j;i<=k;i++) #define fd(i,j,k) for(int i=j;i>=k;i--) using namespace std; int const maxn=2*1e5,inf=1e9; int n,m,p,fa[maxn+10][10],num[maxn+10][10],gra,to[maxn*2+10],next[maxn*2+10], begin[maxn+10],f[maxn+10],tag[maxn+10],u[maxn+10],v[maxn+10],uu[maxn+10],vis[maxn+10], vv[maxn+10],dep[maxn+10]; int get(int x,int p){ if(!fa[x][p])return x; return fa[x][p]=get(fa[x][p],p); } int connect(int x,int y,int p){ int fau=get(x,p),fav=get(y,p); if(fau==fav)return 0; fa[fau][p]=fav; num[fav][p]+=num[fau][p]; return 1; } void insert(int x,int y){ to[++gra]=y; next[gra]=begin[x]; begin[x]=gra; } void dfs(int now,int pre){ vis[now]=1; for(int i=begin[now];i;i=next[i])if(to[i]!=pre){ f[to[i]]=now;dep[to[i]]=dep[now]+1; dfs(to[i],now); } } int main(){ freopen("d.in","r",stdin); freopen("d.out","w",stdout); scanf("%d%d%d",&n,&m,&p); fo(i,1,n)num[i][0]=num[i][1]=1;int cnt=0,tmppp=0; fo(i,1,m){ scanf("%d%d",&u[i],&v[i]); if(connect(u[i],v[i],0)){insert(u[i],v[i]),insert(v[i],u[i]);tmppp++;} else uu[++cnt]=u[i],vv[cnt]=v[i]; } fo(i,1,p){ scanf("%d%d",&u[i],&v[i]); if(connect(u[i],v[i],0)){ tag[i]=1;tmppp++; insert(u[i],v[i]);insert(v[i],u[i]); } } fo(i,1,n)if(!vis[i]){ dep[i]=1;dfs(i,0); } fo(i,1,cnt){ int fau=uu[i],fav=vv[i],tmp,tmpp=0; while((fau=get(fau,1))!=(fav=get(fav,1))){ if(dep[fau]<dep[fav])swap(fau,fav); connect(fau,f[fau],1); //if((fau==get(fau,1))&&(fav==get(fav,1)))tmpp++; //if(tmpp>10)break; } } fo(i,1,p)if(tag[i])printf("No\n");else{ int fau=u[i],fav=v[i],tmp,tmpp=0;; while((fau=get(fau,1))!=(fav=get(fav,1))){ if(dep[fau]<dep[fav])swap(fau,fav); connect(fau,f[fau],1); //if((fau==get(fau,1))&&(fav==get(fav,1)))tmpp++; //if(tmpp>10)break; } printf("%d\n",num[get(fau,1)][1]); } return 0; }
相关文章推荐
- [jzoj]3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)(图论题,构树+缩点+LCA+并查集)
- 【JZOJ 3875】星球联盟
- 【JZOJ3875】星球联盟(alliance)
- 【JZOJ3875】【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- 【JZOJ 3875】 星球联盟
- 【JZOJ3875】【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- JZOJ 3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- 【NOIP2017练习&BZOJ4998】星球联盟(强联通分量,并查集)
- [BZOJbegin][NOIP十连测热身赛]星球联盟(并查集)
- 【bzoj 入门OJ】[NOIP 热身赛]Problem C: 星球联盟(并查集)
- jzoj1882-亲戚【并查集】
- 星球联盟
- JZOJ5373. 【NOIP2017提高A组模拟9.17】信仰是为了虚无之人 并查集+启发式合并
- 【JZOJ 1152】无线网络(并查集)
- jzoj1373-食物链【并查集】
- 【JZOJ3973】【NOI2015模拟1.10】【NOI2013湖南省队集训】黑白树(wbtree)(并查集)
- jzoj 3453_连通块_并查集
- JZOJ4739 【雅礼联考GDOI2017模拟9.2】Ztxz16学图论 莫队加并查集
- Problem C: 星球联盟(并查集+lca)
- 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)