给定两种操作
1.E I 查询I到根节点的距离
2.I I J 将I的父节点设为J,I,J的距离变为|I-J|%1000。
在查找结点的时候顺便把结点到根节点的距离更新。
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <climits> 4 #include <cstring> 5 #include <cstdlib> 6 #include <cmath> 7 #include <vector> 8 #include <queue> 9 #include <algorithm> 10 #define esp 1e-6 11 #define pb push_back 12 #define in freopen("in.txt", "r", stdin); 13 #define out freopen("out.txt", "w", stdout); 14 #define print(a) printf("%d\n",(a)); 15 #define bug puts("********))))))"); 16 #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++) 17 #define inf 0x0f0f0f0f 18 using namespace std; 19 typedef long long LL; 20 typedef vector<int> VI; 21 typedef pair<int, int> pii; 22 typedef vector<pii,int> VII; 23 typedef vector<int>:: iterator IT; 24 25 #define N 22222 26 int pa[N], dis[N]; 27 void init(void) 28 { 29 for(int i = 0; i < N; i++) 30 pa[i] = i, dis[i] = 0; 31 } 32 inline int findset(int x) 33 { 34 if(pa[x] == x) 35 { 36 return x; 37 } 38 else 39 { 40 int r = findset(pa[x]); 41 dis[x] += dis[pa[x]]; 42 return pa[x] = r; 43 } 44 } 45 int main(void) 46 { 47 48 int T, n; 49 for(int t = scanf("%d", &T); t <= T; t++) 50 { 51 init(); 52 scanf("%d", &n); 53 char op[10]; 54 while(scanf("%s", op) && op[0] != 'O') 55 { 56 int u, v; 57 if(op[0] == 'E') 58 { 59 scanf("%d", &u); 60 findset(u); 61 printf("%d\n", dis[u]); 62 } 63 else 64 { 65 scanf("%d%d", &u, &v); 66 dis[u] = (int)fabs(u-v)%1000; 67 pa[u] = v; 68 } 69 } 70 } 71 return 0; 72 }