给你M个区间和,问你有几个是与前面矛盾的。
pre[i]=j 表示点i能到达的最左端的点是j,sum[i]=k,表示i点到j点的距离为k.
#include<iostream> #include<cstdio> #define maxn 200005 using namespace std; int pre[maxn],sum[maxn]; int Find(int x) { int k=pre[x]; if(k!=x) { pre[x]=Find(pre[x]); sum[x]+=sum[k]; } return pre[x]; } int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { int ans=0; for(int i=0;i<=n;i++) pre[i]=i,sum[i]=0; while(m--) { int x,y,z,f1,f2; cin>>x>>y>>z; x--; f1=Find(x),f2=Find(y); if(f1==f2) { if(sum[y]!=sum[x]+z) ans++; } else if(f1>f2) { pre[f1]=f2; sum[f1]=sum[y]-sum[x]-z; } else if(f1<f2) { pre[f2]=f1; sum[f2]=sum[x]-sum[y]+z; } } cout<<ans<<endl; } return 0; }
并查集模板
//hdu1213
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 1005 using namespace std; int pre[maxn],n,m; int Find(int x) { return pre[x]==x?x:pre[x]=Find(pre[x]); } void unite(int x,int y) { int f1,f2; f1=Find(x),f2=Find(y); if(f1!=f2) pre[f2]=f1; } int main() { int t; cin>>t; while(t--) { cin>>n>>m; for(int i=1;i<=n;i++) pre[i]=i; for(int i=1;i<=m;i++) { int a,b; cin>>a>>b; unite(a,b); } int ans=0; for(int i=1;i<=n;i++) if(pre[i]==i) ans++; cout<<ans<<endl; } return 0; }