Sample Input
2
3 3
T 1 2
T 3 2
Q 2
3 4
T 1 2
Q 1
T 1 3
Q 1
Sample Output
Case 1:
2 3 0
Case 2:
2 2 1
3 3 2
note部分:
在unite之前,会进行find(1)操作,此时要进行路径压缩,先找到父结点tf=father[1]=2。
然后继续调用find函数找代表元,找到后,返回给上层。一层一层返回,并加上父亲结点到根结点(此时还没有真正unite,所以根节点还是2)的距离(trans[2]=0),就得到自身到根节点(2)的距离(trans[1] += trans[2] = 1)。
#include <iostream>
using namespace std;
const int maxn = 100;
int father[maxn];
int num[maxn]; //每个城市拥有的龙珠数
int trans[maxn]; //每个龙珠被运送的次数
int N;
void init()
{
for (int i = 1; i <= N; i++)
{
father[i] = i;
num[i] = 1;
trans[i] = 0;
}
}
int find(int x)
{
if (father[x] == x)
{
return x;
}
else
{
int tf = father[x];
father[x] = find(father[x]);
trans[x] += trans[tf];
return father[x];
}
}
void unite(int x, int y)
{
int faX = find(x);
int faY = find(y);
father[faX] = faY;
num[faY] += num[faX];
trans[faX]++;
}
int main()
{
int T;
scanf("%d", &T);
int Q;
int count = 0;
while (T--)
{
scanf("%d%d", &N, &Q);
init();
for (int i = 1; i <= Q; i++)
{
char ope[3];
scanf("%s", ope);
if (ope[0] == 'T')
{
int x, y;
scanf("%d%d",&x,&y);
unite(x, y);
}
else if (ope[0] == 'Q')
{
int a;
scanf("%d", &a);
cout << "Case " << count++ << ":" << endl;
int v = find(a);
cout << v << ' ' << num[v] << ' ' << trans[a] << endl;
}
}
}
return 0;
}
代码超时了。。。先放着。。