HDU - 3635Dragon Balls (简单的带权吧)

题意:


有标号为1到n的n个龙珠,分别放在对应标号为1到n的n个城市里。 
下面有两种操作: 
T A B表示把A龙珠所在城市的所有龙珠都转移到B龙珠所在的城市中 
Q A 表示查询A,需要知道A龙珠现在所在的城市,A所在的城市有几颗龙珠,A转移到这个城市移动了多少次,分别输出3个整数,表示上述信息。

思路:

num数组记录当前城市有多少龙珠。

dis 数组记录当前节点到根节点一共走了多少次。

路径压缩更新节点。

#include <bits/stdc++.h>
#define mem(x,v) memset(x,v,sizeof(x)) 
#define go(i,a,b)  for (int i = a; i <= b; i++)
#define og(i,a,b)  for (int i = a; i >= b; i--)
using namespace std;
typedef long long LL;
const double EPS = 1e-10;
const int INF = 0x3f3f3f3f;
const int N = 1e4+100;
int fa[N],num[N],dis[N];
int n,m;
int find(int k){
	if (fa[k]== k)return k;
	int temp = fa[k]; //路径压缩。
	fa[k] = find(fa[k]);
	dis[k] += dis[temp];
	return fa[k];
}
void init(){
	char ch;
	scanf("%d%d",&n,&m);
	go(i,0,n+1) dis[i] = 0,fa[i] = i,num[i] = 1;
	go(i,1,m){
		int x,y;
		// cin>>ch; //用cin会超时,tm
		scanf("%c",&ch); scanf("%c",&ch);
		if (ch == 'T'){
			scanf("%d%d",&x,&y);
			int fx,fy;
			fx = find(x); fy = find(y);
			if (fx != fy){
				fa[fx] = fy;
				dis[fx] = 1; //每次转移一个城市,移动次数都会 +1;
				num[fy] += num[fx];
			}
		} else{
			scanf("%d",&x);
			y = find(x);
			printf("%d %d %d\n",y,num[y],dis[x]);
		}
	}

}
int main(){
	int T,num = 1; scanf("%d",&T);
	while(T--){
		printf("Case %d:\n",num++);
		init();
	}


	return 0;
}

猜你喜欢

转载自blog.csdn.net/kidsummer/article/details/81737007