题意:
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;
}