带权并查集
【概述】 1、定义:带权并查集即是结点存有权值信息的并查集。
2、适用:当两个元素之间的关系可以量化,并且关系可以合并时,可以使用带权并查集来维护元素之间的关系。
3、权值:带权并查集每个元素的权通常描述其与并查集中祖先的关系,这种关系如何合并,路径压缩时就如何压缩。
4、与并查集的区别:带权并查集可以推算集合内点的关系,而一般并查集只能判断属于某个集合。
【具体实现】
例:https://hihocoder.com/problemset/problem/1515
#include <iostream> #include <cstdio> using namespace std; const int maxn=100005; int n,m,q; int f[maxn],v[maxn];//i的父亲,i与v[i]之间的关系; void init() { for(int i=1;i<=n;i++){ f[i]=i,v[i]=0; } } int fin(int x) { if(x!=f[x]){ int fa=f[x]; f[x]=fin(f[x]); v[x]+=v[fa]; } return f[x]; } int unit(int x,int y,int s) { int fa=fin(x); int fb=fin(y); if(fa!=fb){ f[fa]=fb; v[fa]=s-v[x]+v[y]; } } bool same(int x,int y) { return fin(x)==fin(y); } int main() { scanf("%d%d%d",&n,&m,&q); int a,b,c; init(); for(int i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); unit(a,b,c); } for(int i=0;i<q;i++) { scanf("%d%d",&a,&b); if(!same(a,b)){ printf("-1 "); }else{ printf("%d ",v[a]-v[b]); } } return 0; }