帶權並查集【洛谷P1196】
阿新 • • 發佈:2018-11-21
傳送門:https://www.luogu.org/problemnew/show/P1196#sub
大家都說並查集按秩合併並沒有用,所以我以後大概也不會寫按秩合併了。
而且帶權並查集,不能寫按秩合併好像!
普通的並查集只能維護在不在同一個集合,合併到同一個集合,但是帶權並查集就可以維護很多很多東西啦。
比如這個題目,我們就用帶權並查集維護隊伍的長度。還要維護字首和。
注意:帶權並查集的find函式不能隨便寫,因為每一次find都會壓縮路徑然後搞亂掉權值。
所以在需要的時候儘可能少的寫find,這就是我的理解吧。如果有不會的請指出來哈
下面上程式碼,我們維護字首和就完事了。
#include <bits/stdc++.h> using namespace std; const int maxn = 3e5+7; int p[maxn],s[maxn]; int sum[maxn]; void init() { for(int i=0;i<maxn;i++) { p[i] = i; s[i] = 1; } } int find(int x) { if(p[x]==x) return x; int f = find(p[x]); sum[x] += sum[p[x]]; return p[x] = f; } void unite(int x,int y) { x = find(x); y = find(y); if(x==y) return; p[x] = y; s[y] += s[x]; s[x] = 0; } bool same(int x,int y) { return find(x)==find(y); } int main() { int T; cin>>T; init(); while(T--) { char op; int x,y; cin>>op>>x>>y; int fx = find(x); int fy = find(y); if(op=='M') { sum[fx] += s[fy]; p[fx] = fy; s[fy] += s[fx]; s[fx] = 0; } else { if(fx!=fy) { cout<<-1<<endl; } else { cout<<abs(sum[x]-sum[y])-1<<endl; } } } return 0; }