(补题 Uva 3027)Corporative Network
原题链接(戳我~)
题目大意&解题思路
有n个节点,然后执行I_u_v(把u的父节点设为v)和E_u(询问u到根节点的距离)。
利用带权并查集
Sample Input
1
4
E 3
I 3 1
E 3
I 1 2
E 3
I 2 4
E 3
O
Sample output
0
2
3
5
代码样例
利用pair存放父节点(first)以及权值(second)
计算距离
rela[a].second = ((int)(fabs(a - b))) % 1000;
查找根节点(find_root)
这里住一定不要先压缩再将权值相加(会漏掉某些节点的权值)
int find_root(int x){
if (x == rela[x].first)
return x;
int x_root = find_root(rela[x].first);
rela[x].second += rela[rela[x].first].second;
return rela[x].first = x_root;
}
完整代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <set>
#include <string>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
// typedef long long LL;
const int maxn = 200010;
pair<int, int> rela[maxn]; //first is father root second is value;
//value means the distinct between root & point;
void init()
{
for (int i = 0; i < maxn; i++)
{
rela[i].first = i;
rela[i].second = 0;
}
}
int find_root(int x)
{
if (x == rela[x].first)
return x;
int x_root = find_root(rela[x].first);
rela[x].second += rela[rela[x].first].second;
return rela[x].first = x_root;
}
void union_vertices(int a, int b)
{
rela[a].first = b;
rela[a].second = ((int)(fabs(a - b))) % 1000;
}
int main()
{
int t;
cin >> t;
while (t--)
{
init();
int n;
cin >> n;
char cmd[10];
while (~scanf("%s", cmd))
{
if (cmd[0] == 'O')
break;
else if (cmd[0] == 'I')
{
int a, b;
scanf("%d%d", &a, &b);
union_vertices(a, b);
}
else
{
int a;
scanf("%d", &a);
find_root(a);
cout << rela[a].second << endl;
}
}
}
// system("pause");
return 0;
}