bzoj4690: Never Wait for Weights(帶權並查集)
題目傳送門
。
解法:
我就寫過一次帶權並查集。
還好他不難想。。
看到這道題我就覺得是帶權並查集。。。
fa[i]表示祖先。
sum[i]表示跟祖先的差值。
xx表示x的祖先,yy表示y的祖先。
那麼每次x和y差w的時候
推式子?
x-xx=sum[x] – xx-x=-sum[x]
y-yy=sum[y]
y-x=w;
xx-yy?
將xx合併到yy。
xx-yy=sum[y]-sum[x]-w
那麼sum[xx]也就等於這個。
然後詢問的話判斷是否在同一個集合裡面。
程式碼實現:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
int sum[110000],fa[110000];
int findfa(int x) {
if(fa[x]!=x) {
int tt=fa[x];
fa[x]=findfa(fa[x]);sum[x]+=sum[tt];
}return fa[x];
}
int main() {
int n,m;
while(scanf("%d%d",&n,&m)&&n&&m) {
for(int i=1;i<=n;i++)fa[i]=i;memset(sum,0,sizeof(sum));
while(m--) {
char s[5];int a,b,w;
scanf("%s%d%d",s+1,&a,&b);
if(s[1]=='!') {
scanf("%d",&w);
int xx=findfa(a),yy=findfa(b);
if(xx!=yy) {fa[xx]=yy;sum[xx]=sum[b]-sum[a]-w;}
}
else {
int xx=findfa(a),yy=findfa(b);
if(xx!=yy)printf("UNKNOWN\n");
else printf("%d\n",sum[b]-sum[a]);
}
}
}
return 0;
}
相關文章
- 並查集到帶權並查集並查集
- 【資料結構】帶權並查集資料結構並查集
- 樹(tree) - 題解(帶權並查集)並查集
- 【帶權並查集】理論和應用並查集
- POJ 2492-A Bug's Life(帶權並查集)並查集
- 【並查集】【帶偏移的並查集】食物鏈並查集
- HDU 3038 How Many Answers Are Wrong (帶權並查集)並查集
- 關押罪犯 擴充套件域並查集 帶權並查集 二分圖+二分套件並查集
- CHOJ 4101 銀河英雄傳說【邊帶權並查集】並查集
- POJ 2492 A bug's life【擴充套件域 | 邊帶權並查集】套件並查集
- POJ 1182 食物鏈【擴充套件域 | 邊帶權並查集】套件並查集
- 並查集(一)並查集的幾種實現並查集
- 3.1並查集並查集
- 並查集(小白)並查集
- [kuangbin帶你飛]專題五 並查集 題解並查集
- Luogu P1196 [NOI2002]銀河英雄傳說:帶權並查集並查集
- 並查集(Union Find)並查集
- 並查集應用並查集
- The Door Problem 並查集並查集
- 並查集練習並查集
- 並查集的使用並查集
- 並查集—應用並查集
- 寫模板, 並查集。並查集
- 並查集跳躍並查集
- 各種並查集並查集
- 食物鏈(並查集)並查集
- 並查集(二)並查集的演算法應用案例上並查集演算法
- The Suspects-並查集(4)並查集
- [leetcode] 並查集(Ⅰ)LeetCode並查集
- [leetcode] 並查集(Ⅱ)LeetCode並查集
- [leetcode] 並查集(Ⅲ)LeetCode並查集
- 並查集演算法並查集演算法
- 並查集深度應用並查集
- 【轉】種類並查集並查集
- 並查集java實現並查集Java
- 並查集-Java實現並查集Java
- 並查集題目合集並查集
- 並查集以及應用並查集