并查集 How Many Answers Are Wrong HDU

给你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; }
原文地址:https://www.cnblogs.com/Twsc/p/7272340.html