题意:
n个值,m次查询,每次查询给出(u,v,w)表示位置u到v的值的和,求与前面已出现过的查询中冲突的个数,同时认为这个查询是错误的,忽略它。
题解:
带权并查集。
关于带权并查集可以参考这篇博客
注意连边的时候使用(u-1,v,w)或者(u,v+1,w),不然如果出现(1,10,100),(7,10,28),(1,3,32),(4,6,41) 就查不出来。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
#define m_p make_pair
#define p_b push_back
#define For(i,a,b) for(int i=a;i<=b;i++)
#define ls (rt<<1)
#define rs ((rt<<1)|1)
#define mst(a,b) memset(a,b,sizeof(a))
const int MAXN=2e5+5;
const db eps=1e-8;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const int seed=131;
int n,m;
int fa[MAXN],sum[MAXN];
void init(int n){
For(i,0,n) fa[i]=i,sum[i]=0;
}
int find(int x){
if(fa[x]!=x){
int tt=fa[x];
fa[x]=find(fa[x]);
sum[x]+=sum[tt];
}
return fa[x];
}
int main(){
// freopen("in.txt","r",stdin);
while(~scanf("%d %d",&n,&m)){
init(n);
int u,v,w,ans=0;
For(i,1,m){
scanf("%d %d %d",&u,&v,&w);
int fu=find(u-1),fv=find(v);
if(fu!=fv){
fa[fu]=fv;
sum[fu]=-sum[u-1]+sum[v]+w;
}
else if(w!=sum[u-1]-sum[v]) ans++;
}
cout<<ans<<"\n";
}
return 0;
}