https://www.acmicpc.net/problem/3830
문제
상근이는 매일 아침 실험실로 출근해서 샘플의 무게를 재는 일을 하고 있다. 상근이는 두 샘플을 고른 뒤, 저울을 이용해서 무게의 차이를 잰다.
교수님의 마음에 들기 위해서 매일 아침부터 무게를 재고 있지만, 가끔 교수님이 실험실에 들어와서 상근이에게 어떤 두 샘플의 무게의 차이를 물어보기도 한다. 이때, 상근이는 지금까지 잰 결과를 바탕으로 대답을 할 수도 있고, 못 할 수도 있다.
상근이는 결과를 출근한 첫 날부터 공책에 적어 두었다. 하지만, 엄청난 양의 무게가 적혀있기 때문에, 교수님의 질문에 재빨리 대답할 수가 없었다. 이런 상근이를 위해서 프로그램을 만들려고 한다.
상근이가 실험실에서 한 일이 순서대로 주어진다. 어떤 두 샘플의 무게의 차이를 구할 수 있는지 없는지를 알아내는 프로그램을 작성하시오.
입력
입력은 여러 개의 테스트 케이스로 이루어져 있다.
각 테스트 케이스의 첫째 줄에는 샘플의 종류의 개수 N (2 ≤ N ≤ 100,000)과 상근이가 실험실에서 한 일의 수 M (1 ≤ M ≤ 100,000)이 주어진다. 샘플은 1번부터 N번까지 번호가 매겨져 있다. 다음 M개 줄에는 상근이가 실험실에서 한 일이 주어진다.
상근이가 무게를 쟀다면, ! a b w와 같은 형식으로 주어진다. 이 뜻은 b가 a보다 w그램 무겁다는 뜻이다. (a ≠ b) w는 1,000,000을 넘지 않는 음이 아닌 정수이다. 모든 측정은 정확하고, 일관성을 유지한다.
교수님의 질문은 ? a b와 같은 형식으로 주어진다. 이 뜻은 b가 a보다 얼마나 무거운지를 출력하라는 뜻이다.
마지막 줄에는 0이 두 개 주어진다.
출력
교수님의 질문 (? a b)이 입력으로 들어올 때 마다, 지금까지 측정한 결과를 바탕으로 a와 b의 무게 차이를 계산할 수 있다면, b가 a보다 얼마나 무거운지를 출력한다. 무게의 차이의 절댓값이 1,000,000을 넘지 않는다. 만약, 측정한 결과를 바탕으로 무게의 차이를 계산할 수 없다면, "UNKNOWN"을 출력한다.
예제 입력 1
2 2
! 1 2 1
? 1 2
2 2
! 1 2 1
? 2 1
4 7
! 1 2 100
? 2 3
! 2 3 100
? 2 3
? 1 3
! 4 3 150
? 4 1
0 0
예제 출력 1
1
-1
UNKNOWN
100
200
-50
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long ll;
int N, M;
ll ans;
ll p[100010];
ll diff[100010];
ll find(ll a) {
if (p[a] == a) {
return a;
}
else {
int t = p[a];
p[a] = find(p[a]);
diff[a] += diff[t];
return p[a];
}
}
void Union(ll a, ll b, ll c) {
if (a > b) {
ll t = a;
a = b, b = t;
c = -c;
}
find(a); find(b);
ll x = diff[b], y = diff[a];
a = find(a); b = find(b);
p[b] = a; diff[b] = c + y - x;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
while (true) {
cin >> N >> M;
if (N == 0 && M == 0) {
break;
}
for (int i = 0; i <= N; i++)
{
p[i] = i;
diff[i] = 0;
}
for (int i = 0; i < M; i++)
{
char a;
cin >> a;
if (a == '!') {
int x, y, z;
cin >> x >> y >> z;
Union(x, y, z);
}
else {
int x, y;
cin >> x >> y;
if (find(x) == find(y)) {
cout << diff[y] - diff[x] << "\n";
}
else {
cout << "UNKNOWN\n";
}
}
}
}
return 0;
}
'개발자 > algorithm' 카테고리의 다른 글
백준 11404번 : 플로이드 (c++) (0) | 2020.08.20 |
---|---|
백준 11657번 : 타임머신 (c++) (0) | 2020.08.20 |
백준 1753번 : 최단경로 (c++) (0) | 2020.08.19 |
백준 5719번 : 거의 최단 경로 (c++) (0) | 2020.08.19 |
백준 1854번 : K번째 최단경로 찾기 (c++) (0) | 2020.08.19 |