首页 > 代码库 > HDU 3038 How Many Answers Are Wrong

HDU 3038 How Many Answers Are Wrong

http://acm.hdu.edu.cn/showproblem.php?pid=3038

这是一道并查集题目,这并查集感觉好难写,构思花了我很长很长时间,不过打码时间很短。考虑清楚之后明显快多了

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstdlib>
#define N 200010
using namespace std;
int a[N],sum[N];
int main()
{
    int deal(int x,int y,int val);
    int n,m;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        for(int i=0;i<=n;i++)
        {
            a[i] = i;
        }
        int ans = 0;
        memset(sum,0,sizeof(sum));
        for(int i=1;i<=m;i++)
        {
            int x,y,val;
            scanf("%d %d %d",&x,&y,&val);
            int k = deal(x,y,val);
            if(k==0)
            {
                ans++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
int find(int x,int &val)
{
    int res = 0;
    int k1,k2;
    k1 = x;
    while(x!=a[x])
    {
        res+=sum[x];
        x = a[x];
    }
    val = res;
    while(k1!=a[k1])
    {
        int pre = sum[k1];
        sum[k1] = res;
        res-=pre;
        k2 = a[k1];
        a[k1] = x;
        k1 = k2;
    }
    return x;
}
int deal(int x,int y,int val)
{
    int xx = x;
    int yy = y;
    int val1=0,val2=0;
    xx = find(x-1,val1);
    yy = find(y,val2);
    if(xx==y)
    {
        if(val1!=val)
        {
            return 0;
        }
        return 1;
    }
    if(xx==yy)
    {
        if(val1-val2!=val)
        {
            return 0;
        }
        return 1;
    }
    if(xx<y)
    {
        sum[xx]+=(val-val1);
        a[xx] = y;
    }else if(xx<yy)
    {
        sum[xx]+=(val2-(val1-val));
        a[xx]=yy;
    }else if(xx>yy)
    {
        sum[yy]+=(val1-val-val2);
        a[yy] = xx;
    }
    return 1;
}