hdu3047Zjnu Stadium 带权并查集

//n列个座位,排数为无穷
//m个询问
//a,b,x ,a在b前面x列
//问这m个询问与其前面询问冲突的有多少个 
//带权并查集存下每个点到这个集合中最前的距离
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 50010 ;
int F[maxn] ;
int v[maxn] ;
int n , m ;
int find(int x)
{
    if(x == F[x])
    return F[x] ;
    int t = F[x] ;
    F[x] = find(t) ;
    v[x] += v[t] ;
    return F[x] ;
}
bool join(int x , int y , int num)
{
    int fx = find(x) ;
    int fy = find(y) ;
    if(fx == fy&&v[y] != v[x] + num)
    return false ;
    else if(fx == fy)return true ;
    else
    {
        if(v[x] + num > v[y])
        {
            F[fy] = fx;
            v[fy] = v[x] + num - v[y] ;
        }
        else
        {
            F[fx] = fy ;
            v[fx] = v[y] - (v[x] + num) ;
        }
        return true ;
    }
}
int main()
{
    //freopen("in.txt" ,"r" , stdin) ;
    while(~scanf("%d%d" ,&n , &m))
    {
        for(int i = 1;i <= n;i++)
        F[i] = i ,v[i] = 0;
        int ans = 0 ;
        while(m--)
        {
            int a , b , x ;
            scanf("%d%d%d" ,&a , &b , &x) ;
            if(!join(a , b , x))
            ans++ ;
        }
        cout<<ans<<endl;
    }
    return 0 ;
}

你可能感兴趣的:(并查集)