HDU 3038带权并查集

it2025-05-01  14

#include <bits/stdc++.h> #define ll long long const int maxn = 1e6+10; using namespace std; int par[maxn]; int height[maxn]; int sum[maxn]; void init(){ for(int i = 0; i <= maxn; i++){ par[i] = i; height[i] = 0; //树的高度 sum[i] = 0; } } int Find(int x){ if(x != par[x]){ int f = par[x]; par[x] = Find(par[x]); //路径压缩 sum[x] += sum[f]; } return par[x]; } void merge_set(int a, int b,int val){ //优化合并操作 int fa = Find(a); int fb = Find(b); if (height[fa] == height[fb]) { height[fa] = height[fa] + 1; //合并,树的高度加一 par[fb] = fa; sum[fb] = -sum[b] + sum[a] -val; } else{ //把矮树并到高树上,高树的高度保持不变 if (height[fa] < height[fb]) par[fa] = fb,sum[fa] = -sum[a] + sum[b] +val; else par[fb] = fa,sum[fb] = -sum[b] + sum[a] -val; } } int main() { int n,m; int ans; while(~scanf("%d%d",&n,&m)) { ans = 0; init(); int a,b,val; for(int i = 0;i < m;i++) { scanf("%d%d%d",&a,&b,&val); a--; int fa = Find(a); int fb = Find(b); if(fa != fb) { merge_set(a,b,val); } else{ if(sum[a] - sum[b] != val)ans++; } } cout<<ans<<endl; } return 0; }
最新回复(0)