UVALive 3027 - Corporative Network(带权并查集)
题目大意:
输入t表示一共有 t 组测试数据,输入 n 表示有n座城市,然后输入一些命令,这些命令以字母‘O’ 结束,E i 表示 i 城市到他的父亲节点的距离,I i j表示将 i 和 j 城连起来,j 是 i 的父亲。
解题思路:
带权并查集。比赛的时候也没想到,实际上和之前并查集差不多,只要改一下find函数就可以了,再维护一个dis数组,dis i 表示 i 城到父节点的距离是多少(距离abs(i-j)%1000),每一个E命令 输出一个距离。
对find函数的解释:x节点到x根节点的距离 = x的距离到x父亲节点的距离+父亲节点根节点的距离(套娃),递归的去求距离,最终更新的dis[x] 即为 x 到根节点的距离。
AC代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int _max = 2e4+50;
int f[_max],dis[_max],t,n;
int find(int x)//路径压缩+寻根+求距离
{
if(x==f[x])
return x;
else
{
int t=f[x];//x的父亲节点
f[x]=find(f[x]);//父亲节点去寻根
dis[x]+=dis[t];//递归的去更新距离
return f[x];
}
}
int main()
{
cin>>t;
while(t--)
{
cin>>n;
for(int i=0;i<=n;i++)
{
f[i]=i;
dis[i]=0;
}
char ch;
while(cin>>ch)
{
if(ch=='O')
break;
int i,j;
if(ch=='I')
{
cin>>i>>j;
f[i]=j;
dis[i]=abs(i-j)%1000;//更新后距离也要更新
}
else
{
cin>>i;
find(i);//求i节点到根节点的距离
cout<<dis[i]<<endl;
}
}
}
//system("pause");
return 0;
}