hdu3047Zjnu Stadium 带权并查集

来源:互联网 发布:万科华润宝能大战知乎 编辑:程序博客网 时间:2024/06/14 01:48
//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 ;}
0 0
原创粉丝点击