白駿3830号:教授は待たない
質問する
題ショートカットキー>白駿3830号:教授は待たない
に答える
union & find
を利用して問題を解く.重量を比較できる場合は同じ集合に配置し、dist
配列を用いてルートノードからノードへの重量差を計算する.#include<iostream>
#include<cstring>
#define MAX_N 100001
using namespace std;
int N, M, a, b, w;
char op;
int parent[MAX_N];
long long dist[MAX_N]; // dist[x]=y : node x 는 root node 보다 y만큼 무겁다!
int find(int node){
if(parent[node] == node) return node; // root node의 번호는 자기 자신
int p = find(parent[node]); // 상위 node dist 먼저 update
dist[node]+=dist[parent[node]]; // dist update
return parent[node] = p;
}
void uni(int a, int b, int w){
int roota = find(a), rootb = find(b); // a, b의 루트 노드를 찾음
if(roota == rootb) return;
dist[rootb] = dist[a]-dist[b]+w; // dist 저장
parent[rootb] = roota; // b를 a의 자손으로 넣어 두 트리를 합침
}
int main(){
while (1){
ios_base::sync_with_stdio(0); cin.tie(0);
cin >> N >> M;
if(N==0 && M==0) return 0;
for(int i=0; i<=N; i++) parent[i] = i; // 처음에 root node는 자신
memset(dist, 0, sizeof(dist)); // dist 배열 초기화
while (M--){
cin>> op;
if(op=='!'){ // 무게를 재는 경우
cin >> a >> b >> w;
uni(a, b, w);
}
else if(op=='?'){ // 교수님의 질문인 경우
cin >> a >> b;
if(find(a)!=find(b)) cout << "UNKNOWN\n"; // 비교가 불가능한 경우
else cout << dist[b]-dist[a] << '\n'; // 비교가 가능한 경우
}
}
}
}
Reference
この問題について(白駿3830号:教授は待たない), 我々は、より多くの情報をここで見つけました https://velog.io/@danbibibi/백준-3830번-교수님은-기다리지-않는다テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol