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 ,表示不能回答問題。
第一道帶權並查集的題目,還挺好懂的,注意下細節,多複習…… 代碼:
#include<cstdio>#include<cstring>const int maxn=100005;int f[maxn],d[maxn];int findfa(int x){if(f[x]==x) return x;//d[x]+=d[f[x]];int oldfa=f[x];f[x]=findfa(f[x]);d[x]+=d[oldfa];return f[x];}void work(int x,int y,int z){int fx=findfa(x),fy=findfa(y);//if(fx==fy) return;f[fx]=fy;d[fx]=d[y]+z-d[x];}int main(){int n,m;while(1){scanf("%d%d",&n,&m);if(n==0 && m==0) break;for(int i=1;i<=n;i++) f[i]=i,d[i]=0;for(int i=1;i<=m;i++){char s[3];int x,y,z;scanf("%s%d%d",s,&x,&y);if(s[0]=='!'){scanf("%d",&z);work(x,y,z);}else {int fx=findfa(x),fy=findfa(y);if(fx!=fy) printf("UNKNOWN\n");else printf("%d\n",d[x]-d[y]);}}}}