【CTSC1999】月亮之眼
Description
吉兒是一家古董店的老闆娘,由於她經營有道,小店開得紅紅火火。昨天,吉兒無意之中得到了散落民間幾百年的珍寶—月亮之眼。吉兒深知“月亮之眼”價值連城:它是由許多珍珠相連而成的,工匠們用金線連線珍珠,每根金線連線兩個珍珠;同時又對每根金線染上兩種顏色,一半染成銀白色,一半染成黛黑色。由於吉兒自小熟讀古籍,所以還曉得“月亮之眼”的神祕傳說:“月亮之眼”原是一個古代寺廟的寶物,原本是掛在佛堂的一根頂樑柱上的,整個寶物垂直懸掛,所有珍珠排成一線,且都鑲嵌在柱子裡,而每一根金線又都是繃緊的,並且金線的銀白色一端始終在黛黑色一端的上方;然而,在一個月圓之夜,“月亮之眼”突然從柱裡飛出,掉落下來,寶物本身完好無損,只是僧侶們再也無法以原樣把“月亮之眼”嵌入柱子中了。吉兒望著這個神祕的寶物,回憶著童年讀到的傳說,頓時萌發出恢復“月亮之眼”的衝動,但是擺弄了幾天依舊沒有成功。
您要設計一個程式,對於給定的“月亮之眼”進行周密分析,然後給出這串寶物幾百年前嵌在佛堂頂樑柱上的排列模樣。給定的“月亮之眼”有N個珍珠和P根金線,所有珍珠按一定順序有了一個序號:1、2…、N。
Input
輸入資料包含一個“月亮之眼”的特徵描述:
檔案第一行有兩個整數N和P,其中N表示寶物中的珍珠個數,P表示寶物中的金線根數;
以下P行描述珍珠連線情況:
檔案第I+1行有三個整數,Ri1,Ri2,Li。其中Ri1表示第I根金線的銀白色一端連線的珍珠序號;Ri2表示第I根金線的黛黑色一端連線的珍珠序號;Li表示第I根金線的長度。
Output
由於珍珠尺寸很小,所以幾個珍珠可以同時鑲嵌在一個位置上。
您的輸出資料描述的是“月亮之眼”各個珍珠在頂樑柱上的位置,輸出檔案共N行:
第I行,一個整數S,它表示標號為I的珍珠在頂樑柱上距離最高位置珍珠的距離。
注意:若無解則輸出僅一行,包含一個整數“-1”。
Sample Input
9 9
1 2 3
2 3 5
2 7 1
4 5 4
5 6 1
5 9 1
6 7 1
7 8 3
9 8 4
Sample Output
2
5
10
0
4
5
6
9
5
Hint
引數限定
1<=N<=255
樣例說明:
我們把輸入依次投射出來,從左到右,具體如下圖:
題意有些難懂 但結合圖片就不難理解了
因為輸出只是離最高的珠子的的距離 我們考慮帶權的並查集並採用路徑壓縮
對於一對珠子 X Y X在Y上方 距離為Z 當XY不在同一並查集時
則有兩種情況
一種在X並查集的樹根XX到Y的距離大於在Y的並查集的樹根YY到Y的距離 (即在這條直線上 XX 高於 YY)
此時連線X——Y 與 連線XX——YY同理 距離為 XX到Y距離去YY到Y的距離(d[x] + Z - d[y])
同理 當YY高於XX也是同理 距離為 YY到Y距離去XX到Y的距離(-d[x] - S + d[y])
當XY在同一並查集時 則必有X Y 到樹根距離為Z 否則不能繃直或連線
貼程式碼
#include<iostream> #include<cstdio> #define LL long long #define f(a,b) for(long long i = (a); i <= (b); i++) using namespace std; long long n,m,sum; long long fa[1000],d[3000]; long long begin,final,value,x,y; void merge(long long xx,long long yy,long long sum) { fa[xx] = yy, d[xx] = sum; } long long get(long long x) { if(x == fa[x]) return x; long long root = get(fa[x]); d[x] += d[fa[x]]; return fa[x] = root; } int main() { scanf("%lld%lld",&n,&m); f(1,n)fa[i] = i,d[i] = 0; f(1,m) { scanf("%lld%lld%lld",&x,&y,&value); long long x_father = get(x),y_father = get(y); if(x_father == y_father) if(d[y] - d[x] != value) { cout<<-1; return 0; } if(d[x] + value >= d[y]) merge(y_father,x_father,d[x] + value - d[y]); if(d[x] + value < d[y]) merge(x_father,y_father,d[y] - value - d[x]); } f(1,n) long long QWQ = get(i); f(1,n)cout << d[i]<<endl; }View Code