본문 바로가기

Dev/Algorithm

[백준] 3830 - 교수님은 기다리지 않는다.

www.acmicpc.net/problem/3830

 

3830번: 교수님은 기다리지 않는다

교수님의 질문 (? a b)이 입력으로 들어올 때 마다, 지금까지 측정한 결과를 바탕으로 a와 b의 무게 차이를 계산할 수 있다면, b가 a보다 얼마나 무거운지를 출력한다. 무게의 차이의 절댓값이 1,000,

www.acmicpc.net

 Union Find를 응용해서 푸는 문제다. !로 시작하는 두 물체간의 무게 비교 결과가 주어질때는 union을 해주고 'diff[a] = a의 무게 - root의 무게'로 정의해서 계산해준다. 두 물체간 비교를 묻는 질의가 들어올때는 두 정점이 서로 Union이 아니면 'UNKNOWN', Union이면 diff[b] - diff[a]의 결과를 출력해주면 된다.

#include <stdio.h>

int N, M;
long long ans;
long long parents[100010];
long long diff[100010];

long long updateParents(long long a)
{
    if (parents[a] == a)
    {
        return a;
    }
    else
    {
        int t = parents[a];
        parents[a] = updateParents(parents[a]);
        diff[a] += diff[t];
        return parents[a];
    }
}

void unionSample(long long a, long long b, long long w)
{
    updateParents(a);
    updateParents(b);
    long long x = diff[b];
    long long y = diff[a];
    a = updateParents(a);
    b = updateParents(b);
    parents[b] = a;
    diff[b] = w + y - x;
}

int main()
{
    while (true)
    {
        scanf("%d%d", &N, &M);
        if (N == 0 && M == 0)
        {
            break;
        }
        for (int i = 0; i <= N; i++)
        {
            parents[i] = i;
            diff[i] = 0;
        }

        for (int i = 0; i < M; i++)
        {
            char q[2];
            scanf("%s", q);
            if (q[0] == '!')
            {
                int a, b, w;
                scanf("%d%d%d", &a, &b, &w);
                unionSample(a, b, w);
            }
            else
            {
                int a, b;
                scanf("%d%d", &a, &b);
                if (updateParents(a) == updateParents(b))
                {
                    printf("%lld\n", diff[b] - diff[a]);
                }
                else
                {
                    printf("UNKNOWN\n");
                }
            }
        }
    }
    return 0;
}