博文:https://blog.csdn.net/yjr3426619/article/details/82315133
带全并查集
路径压缩,表达每个当前node与 当前node所在的并查集的root 之间的关系
并查集一定是单向连通的,所以一些node处理时 【node1,node2】 weight 可能需要把 一端的闭区间变为开区间
俩个相对信息求出绝对信息 --水题
例题 : HDU 3038
//带权值并查集 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 2e5 + 25; int dis[maxn]; int p[maxn]; int find(int u)//寻根 { if(u!=p[u]) { int tmp = p[u];//保存原来的根节点 p[u] = find(p[u]);//路径压缩 dis[u] += dis[tmp];//dis[tmp] 已经为tmp(即原来父节点)到根节点的距离所以加上本身自身到tmp的dis则为u到root的dis } return p[u]; } void merge(int u,int v,int value) { int f1 = find(u); int f2 = find(v); p[f1] = f2; dis[f1] = value + dis[v] - dis[u]; }//带权并查集合并 int main() { int n,m;//n节点,m条边 while(cin>>n>>m) { int ans = 0,u,v,value; for(int i=0;i<=n;++i) { dis[i] = 0; p[i] = i; } while(m--) {//图改成了从0开始(important) cin>>u>>v>>value; --u; if(find(u)==find(v)) { if((dis[u]-dis[v])!=value) ++ans; }else{ merge(u,v,value);//否则合并 } } cout<<ans<<endl; } }