题目描述
佳佳是个贪玩的孩子。一天,他正在跟凡凡玩“数石子”的游戏。佳佳在地上摆了N堆石子,其中第I堆石子有Ai个石头。佳佳每次都会问凡凡:“凡凡,请问从第I堆到第J堆,总共有多少个石子?”聪明的凡凡每次都能快速而准确地回答对。凡凡老是被问问题,心里有些不服,就对佳佳说:“佳佳,你还记得你问了什么问题,我回答了什么答案吗?”佳佳说当然记得。于是凡凡说:“好,我把石子拿走,再问你一些相似的问题,你能答得出来吗?”佳佳张圆了嘴巴,望着凡凡,一脸疑问和惊讶的表情。你现在知道了游戏规则和过程,但没看见原来的石子。请你写一个程序来帮助佳佳。
数据范围
10%的数据满足1<=n<=10,0<=m,k<=10
30%的数据满足1<=n<=500,0<=m,k<=500
100%的数据满足1<=n<=5000,0<=m,k<=10000
输入文件的第一行有3个数N(1<=n<=5000),M,K(0<=m,k<=10000),表示N堆石子,佳佳问了M个问题,凡凡要问K个问题。接下来M行每行3个整数L,R(1<=l<=r<=n),X(-108<=X<=108),表示佳佳问从L堆到R堆的石子共有多少个,而凡凡回答X个。接下来K行每行2个整数A,B(1<=a<=b<=n),每行表示凡凡问从A到B这些堆里的石子有多少个。
输出文件需要对于凡凡提出每一个提问,你若可以回答,则输出答案,若无法回答,输出UNKNOWN。
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 50000 + 5;
int fa[maxn],dist[maxn],N,M,K;
int f(int a) {
if(fa[a] == a) return a;
int root = f(fa[a]);
dist[a] = dist[a] + dist[fa[a]];
fa[a] = root;
return root;
}
void uni(int a,int b,int d) {
a = a - 1;
int ya = f(a),yb = f(b);
if(ya == yb) return;
fa[yb] = a;
dist[yb] = d - dist[b];
}
int main() {
scanf("%d%d%d",&N,&M,&K);
for(int i = 1;i <= N;i++) {
fa[i] = i;
}
for(int i = 1;i <= M;i++) {
int a,b,d; scanf("%d%d%d",&a,&b,&d);
uni(a,b,d);
}
for(int i = 1;i <= K;i++) {
int a,b; scanf("%d%d",&a,&b);
a--;
int ya = f(a),yb = f(b);
if(ya != yb) puts("UNKNOWN");
else {
printf("%d\n",dist[b] - dist[a]);
}
}
return 0;
}