美文网首页
HDU3038(How Many Answers Are Wro

HDU3038(How Many Answers Are Wro

作者: kimoyami | 来源:发表于2018-10-27 14:41 被阅读39次

    链接:https://vjudge.net/problem/HDU-3038
    思路:带权并查集,首先我们要考虑在什么情况下会出错,当且仅当某个区间开头和位置以及和都确定并且产生矛盾的时候,于是我们建立一个带权并查集,每个区间查询其左端点-1的节点(因为左端点也要算在和内)与右端点的节点的祖先节点,如果相同说明通过其他的操作已经可以推算出这个区间的值了(自行思考推理一下),只需要比对一下前后到祖先节点距离的差值是否等于给定的值即可,如果不等则说明没法推断出,则不会产生矛盾,此时将两个端点合并,并且更新各节点到祖先节点的距离。
    代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 200010;
    int par[maxn];
    int n,m;
    int sum[maxn];
    
    int getroot(int a){
        if(par[a]==a)return a;
        int p = par[a];
        par[a] = getroot(par[a]);
        sum[a]+=sum[p];//更新到祖先节点的距离
        return par[a];
    }
    
    int main(){
        while(~scanf("%d%d",&n,&m)){
            int res = 0;
            for(int i=0;i<=n;i++){
                par[i] = i;
                sum[i] = 0;
            }
            for(int i=0;i<m;i++){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                u--;
                int p1 = getroot(u);
                int p2 = getroot(v);
                if(p1==p2){
                    if(sum[v]-sum[u]!=w)res++;//更新答案
                }
                else{
                    par[p2] = p1;
                    sum[p2] = sum[u] - sum[v] + w;//自行画图即可得出该表达式
                }
            }
            printf("%d\n",res);
        }
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:HDU3038(How Many Answers Are Wro

          本文链接:https://www.haomeiwen.com/subject/wardtqtx.html