1. 程式人生 > >BZOJ4690: Never Wait for Weights

BZOJ4690: Never Wait for Weights

測試結果 接下來 led blank 程序 輸入 %s 格式化 rip

Description

在實驗室中,Nathan Wada作為助手的職責是測定兩個樣品的重量差異。當樣品的差異很小時,使用天平能比使用 彈簧秤得到更精確的結果,所以他只使用天平來測得一些樣品的重量差。他偶爾會被詢問一些樣品的重量差,而他 能否回答這些問題取決於在回答相應問題時他已經得到的測量結果。由於他所在處理的測量數據是巨大的,所以他 希望你能寫個程序幫他處理數據和回答問題。

Input

輸入包含多組測試數據。每組數據第一行包含兩個整數 N 和 M ,其中 N 表示樣品的數量, 樣品從 1 到 N 標號,滿足 2≤N≤100000 。 接下來 M 行,每行包括一個測量結果或者詢問,按時間順序給出,滿足 1≤M≤100000 。 一個測量結果被格式化為 ! a b w ,表示第 a 個樣品比第 b 個樣品輕 w 個單位重量 滿足 a≠b,0≤w≤1000000 ,且任意的測試結果互不矛盾。 一個詢問被格式化為 ? a b ,表示詢問第 a 個樣品比第 b 個樣品輕多少個單位重量,滿足 a≠b 。 輸入以兩個零作為結束。

Output

對於每個詢問輸出一行,如果能回答問題,則輸出問題的答案,你可以認為答案的絕對值不超過 1000000 否則輸出 UNKNOWN ,表示不能回答問題。

Sample Input

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

Sample Output

1
-1
UNKNOWN
100
200
-50
題目傳送門 Hans_o推的題,不會做。。 帶權並查集,炒了一波AKC的代碼 代碼如下:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;

int fa[110000];LL d[110000];
int findfa(int x)
{
    if(fa[x]==x)return fa[x];
    int FA=findfa(fa[x]);
    d[x]
+=d[fa[x]];fa[x]=FA; return fa[x]; } char ss[10]; int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0)break; for(int i=1;i<=n;i++)fa[i]=i,d[i]=0LL; int x,y;LL c; for(int i=1;i<=m;i++) { scanf("%s",ss+1); if(ss[1]==!) { scanf("%d%d%lld",&x,&y,&c); int fx=findfa(x),fy=findfa(y); if(fx!=fy) { d[fx]=d[y]+c-d[x]; fa[fx]=fy; } } else { scanf("%d%d",&x,&y); int fx=findfa(x),fy=findfa(y); if(fx!=fy)printf("UNKNOWN\n"); else printf("%lld\n",d[x]-d[y]); } } } return 0; }

by_lmy

BZOJ4690: Never Wait for Weights