带权并查集
Posted LH2000
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了带权并查集相关的知识,希望对你有一定的参考价值。
[HNOI2005]狡猾的商人 - 题目 - 黑暗爆炸OJ (darkbzoj.tk)
注意维护的是边而不是点
s需要-1
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod=998244353; const int N=200005; int prime[1100000],primesize; bool isprime[11000000]; ll f[N],invf[N]; ll inv[N]; void getlist(int listsize){ memset(isprime,1,sizeof(isprime)); isprime[1]=false; for(int i=2;i<=listsize;i++){ if(isprime[i])prime[++primesize]=i; for(int j=1;j<=primesize&&i*prime[j]<=listsize;j++) { isprime[i*prime[j]]=false; if(i%prime[j]==0) break; } } } void extend_gcd(ll a, ll b, ll& d, ll& x, ll& y) { if(!b){ d = a; x = 1; y = 0; } else { extend_gcd(b, a%b,d, y, x); y -= x*(a/b);} } void ni(int n) { inv[0] = inv[1] = 1; for(int i = 2; i <= n; i++) { inv[i] = (mod - (mod/i))*inv[mod%i]%mod; } } ll fpow(ll a,ll k){ ll res=1; while(k){ if(k&1) res=(res*a)%mod; k>>=1; a=a*a%mod; //cout<<1<<endl; } return res; } ll mm(ll a,ll b){ ll ret=0; for(a%=mod;b;b>>=1){ if(b&1){ret+=a;if(ret>=mod)ret-=mod;} a<<=1;if(a>=mod)a-=mod; } return ret; } void init(int n){ f[0]=1; for(int i=1;i<=n;++i){ f[i]=f[i-1]*i%mod; } invf[n]=fpow(f[n],mod-2); for(int i=n-1;i>=0;--i){ invf[i]=invf[i+1]*(i+1)%mod; } } ll C(int n,int k){ if(k<0 || k>n) return 0; return f[n]*invf[k]%mod*invf[n-k]%mod; } ll d[1005]; ll fa[1005]; ll ff(ll x){ if(x==fa[x])return x; ll xx=ff(fa[x]); d[x]+=d[fa[x]]; return fa[x]=xx; } void solve(){ ll n,m; cin>>n>>m; memset(d,0,sizeof(d)); for(int i=0;i<=n;i++){ fa[i]=i; } int flag=1; for(int i=1;i<=m;i++){ ll s,t,v; cin>>s>>t>>v; s--; ll xx=ff(s); ll yy=ff(t); if(xx!=yy){ fa[yy]=xx; d[yy]=d[s]-d[t]+v; } else if(d[t]-d[s]!=v){ flag=0; break; } } if(flag){ cout<<"true"<<endl; } else{ cout<<"false"<<endl; } } int main(){ ios::sync_with_stdio(false);cin.tie(0); // freopen("1.in","r",stdin); // getlist(1e7); int t=1; cin>>t; while(t--){ solve(); } }
以上是关于带权并查集的主要内容,如果未能解决你的问题,请参考以下文章