牛客Professional Manager(並查集)
阿新 • • 發佈:2018-04-30
sam 構造 tin whether closed 模板題 main ont 父親
Thus a professional tree manager is needed. Your task is to write a program to help manage the trees. Initially, there are n forests and for the i-th forest there is only the i-th tree in it. Given four kinds of operations.
, indicating the number of initial forests and the number of operations.
示例1
t’s universally acknowledged that there’re innumerable trees in the campus of HUST.
Thus a professional tree manager is needed. Your task is to write a program to help manage the trees. Initially, there are n forests and for the i-th forest there is only the i-th tree in it. Given four kinds of operations.
1 u v, merge the forest containing the u-th tree and the forest containing the v-th tree;
2 u, separate the u-th tree from its forest;
3 u, query the size of the forest which contains the u-th tree; 4 u v, query whether the u-th tree and the v-th tree are in the same forest.輸入描述:
The first line contains an integer T, indicating the number of testcases.
In each test case:
The first line contains two integers N and Q
Then Q lines follow, and each line describes an operation.
輸出描述:
For each test cases, the first line should be "Case #i:", where i indicate the test case i.
For each query 3, print a integer in a single line.
For each query 4, print "YES" or "NO" in a single line.
輸入
1 10 8 3 1 4 1 2 1 1 2 3 1 4 1 2 2 1 3 1 4 1 2
輸出
Case #1: 1 NO 2 YES 1 NO
這是一道有點宇宙不同的並查集模板題,與其他不同的是多了個刪除操作,那麽我們該怎麽做呢? 可以想到的是直接把要刪除的點的父親結點改成是自己,但是,如果這個點有子節點怎麽辦? 很顯然,這種方法就無法做了,
我們可以給每個點都給他們一個編號,刪除點,就相當於該點的編號改變就可以了,也是相當於構造新點
AC代碼
#include<stdio.h> int n,f[200001],d[200001],h[200001],now; ///f為並查集,d為編號,h為高度 int findd(int x)///查找父節點 { if(f[x]!=x) f[x]=findd(f[x]); return f[x]; } void init () { for(int k=1 ;k<=n ;k++) { f[k]=k; d[k]=k; h[k]=1; } } ///合並 void HB(int u,int v) { u=d[u],v=d[v]; u=findd(u),v=findd(v); if(u==v) return ; f[u]=v; h[v]+=h[u]; } ///刪除 void SC(int u) { int v; v=d[u]; v=findd(v); h[v]--; ++now; d[u]=now; f[now]=now;h[now]=1; } int main() { int t,i,q,x,v,u; scanf("%d",&t); for(i=1 ;i<=t; i++) { printf("Case #%d:\n",i); scanf("%d%d",&n,&q); now=n; init(); while(q--) { scanf("%d",&x); if(x==1) { scanf("%d%d",&u,&v); HB(u,v); } if(x==2) { scanf("%d",&u); SC(u); } if(x==3) { scanf("%d",&u); u=d[u];u=findd(u); printf("%d\n",h[u]); } if(x==4) { scanf("%d%d",&u,&v); u=d[u];v=d[v]; u=findd(u);v=findd(v); if(u==v) printf("YES\n"); else printf("NO\n"); } } } return 0; }View Code
牛客Professional Manager(並查集)