Disjoint-set --UVA - 1329

Here Insert Picture Description

There are n nodes (5 <= n <= 20000 ), are initially each node has no parent node. Your task is to perform the operation I and E operate in the following format:
· I uv: the node's parent node u to v, the distance | uv | mod 1000.
Before Instruction input u ensure no parent node.
· E u: ask u to the root of the distance.

Initially thought of: do not record the distance,
the I: change the parent node
E: Cyclic until you find the root

do{
ans += abs(u - pre[u]) % 1000;
u = pre[u];
}while(u!=pre[u]);
cout << ans << endl;

Thinking he felt quite right.
But Timeout: Do not exceed 10 ^ 7
But suppose that every query longest, will be super.
Therefore, recording with d

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<vector>
#include<cstring>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int maxn = 20005;

int pre[maxn];
int n;
int d[maxn];
int mod = 1000;

//不用join函数,给出的直接是父亲节点
//find:寻找最短的权值相加
int find(int x){
    if(pre[x]==-1)
        return x;
    int t = find(pre[x]);   //往上找
    d[x] += d[pre[x]];
    return pre[x] = t;
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        memset(pre,-1,sizeof(pre));
        memset(d,0,sizeof(d));
        char op;
        int u,v;
        while(~scanf("%c",&op)){
            if(op=='0')
                break;
            else if(op=='E'){
                scanf("%d",&u);
                find(u);
                printf("%d\n",d[u]);
            }
            else if(op=='I'){
                scanf("%d %d",&u,&v);
                pre[u] = v;
                d[u] = abs(u-v) % mod;
            }
        }
    }
    return 0;
}

Published 62 original articles · won praise 0 · Views 1736

Guess you like

Origin blog.csdn.net/jhckii/article/details/104578925