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;
}
posted @ 2020-06-12 23:43  Hayasaka  阅读(56)  评论(0编辑  收藏  举报