HDU3038 How Many Answers Are Wrong

题目大意:有n个数,m行信息,每行包含u,v,val,表示u到v的和为val(这m行的信息不全是正确的),然后让你判断有几次个条件是错的,并输出个数

分析:u->v的和可以理解为v比u大val,然后就变成了并查集的问题,详见代码

\frac{1+sin(x)}{y}
#include<stdio.h>
#include<math.h>
#include<cmath>
#include<queue>
#include<stack>
#include<string>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<functional>
#include<iomanip>
#include<map>
#define pb push_back
using namespace std;
typedef long long ll;
pair<ll,ll>PLL;
const int INF = 0x3f3f3f3f;
const int maxn =1e6+100;
const int N = 1e6;
int ans,n,m;
int sum[maxn];//sum[x]表示x->y的距离
int fa[maxn];
int Find(int x) {
    if(fa[x]==x)
        return x;
    int tmp=Find(fa[x]);    //必须注意
    sum[x]+=sum[fa[x]];        //父节点和子节点距离为sum[fa[x]],因此当子节点更新时,
    return fa[x]=tmp;        // 父节点的距离要先加上上一个子节点到他的距离
}
void unite(int x,int y,int val) {
    int xx=Find(x);
    int yy=Find(y);
    if(xx==yy) {
        if(sum[y]-sum[x]!=val)
            ans++;
    } else {
        fa[yy]=xx;
        sum[yy]=sum[x]-sum[y]+val;
    }
}
void init() {
    for(int i=0; i<=n; i++)
        fa[i]=i;
}
int main() {
    std::ios::sync_with_stdio(false);
    //freopen("in.txt", "r", stdin);
    //    freopen("out.txt","w",stdout);
    while(cin>>n>>m) {
        init();
        ans=0;
        memset(sum,0,sizeof(sum));
        while(m--) {
            int a,b,val;
            cin>>a>>b>>val;
            unite(a-1,b,val);
        }
        cout<<ans<<endl;
    }
    return 0;
}

 

posted @ 2018-02-16 15:42  visualVK  阅读(129)  评论(0)    收藏  举报