标签:
题意:有n个村庄,初始每个村庄有一个龙珠,然后T是将A中的所有龙珠转到B所在的村庄中,然后Q是问A编号的龙珠所在的位置,这个位置的龙珠数量,和A移动的次数
思路:用并查集的路径压缩来完成每个龙珠的转换次数,剩下的两个操作直接用简单的并查集即可完成,而路径压缩也就等价于这个点在走到现在位置所走的路径,那么路径压缩时直接将路过的值加起来就是结果了,画图可以很快看出来他的思想的
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3fll; const int maxn=10010; int f[maxn],num[maxn],time[maxn]; int find1(int x){ if(x==f[x]) return f[x]; int t=f[x]; f[x]=find1(f[x]); time[x]+=time[t]; return f[x]; } void unite(int a,int b){ int aa=find1(a); int bb=find1(b); if(aa==bb) return ; f[aa]=bb;num[bb]+=num[aa]; time[aa]++; } int main(){ int T,cas=1,n,m,u,v; char ch[10]; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); for(int i=0;i<=n;i++){ f[i]=i;num[i]=1;time[i]=0; } printf("Case %d:\n",cas++); for(int i=0;i<m;i++){ scanf("%s",ch); if(ch[0]=='Q'){ scanf("%d",&u); int ans=find1(u); printf("%d %d %d\n",ans,num[ans],time[u]); }else if(ch[0]=='T'){ scanf("%d%d",&u,&v); unite(u,v); } } } return 0; }
标签:
原文地址:http://blog.csdn.net/dan__ge/article/details/51509642