【poj 1962】Corporative Network(图论--带权并查集 模版题)
P.S.我不想看英文原题的,但是看网上题解的题意看得我 炒鸡辛苦&一脸懵 +_+,打这模版题的代码也纠结至极了......不得已只能自己翻译了QwQ 。
题意:有一个公司有N个企业,分成几个网络,分别从各个网络中选一个机器设置为中心机。下面有2种操作:1.查询当前时间机器x到其所在网络的中心机的距离;2.设置中心机x与机器y相连,距离为abs(x-y)%1000,x所在的网络的中心机变为y所在网络的中心机。
解法:带权并查集。可以把中心机转换为一个集合(树)的根节点,求距离就是求点到根节点的距离。于是我们就做并查集的同时维护一个f[i]表示点 i 到其根节点的距离。
请画树理解代码,图解可参考:【bzoj 1202】[HNOI2005] 狡猾的商人(图论--带权并查集+前缀和)
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 7 const int N=20010,mod=1000; 8 int f[N],fa[N]; 9 char s[3]; 10 int n; 11 12 int mabs(int x) {return x>0?x:-x;} 13 int ffind(int x) 14 { 15 if (fa[x]!=x) 16 { 17 int fx=fa[x]; 18 fa[x]=ffind(fx);//更新了fx 19 f[x]+=f[fx];//注意:题意不是全部都取模,只是新连接的长度取模 20 } 21 return fa[x]; 22 } 23 int main() 24 { 25 int T,x,y; 26 scanf("%d",&T); 27 while (T--) 28 { 29 scanf("%d",&n); 30 for (int i=1;i<=n;i++) fa[i]=i,f[i]=0; 31 while (1) 32 { 33 scanf("%s",s); 34 if (s[0]=='O') break; 35 if (s[0]=='E') 36 { 37 scanf("%d",&x); 38 ffind(x);//更新 39 printf("%d\n",f[x]); 40 } 41 else 42 { 43 scanf("%d%d",&x,&y); 44 fa[x]=y;//直接相连 45 f[x]=mabs(x-y)%mod; 46 } 47 } 48 } 49 return 0; 50 }