【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
",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 }
原文地址:https://www.cnblogs.com/konjak/p/6029281.html