How Many Answers Are Wrong HDU - 3038 (经典带权并查集)

题目大意:有一个区间,长度为n,然后跟着m个子区间,每个字区间的格式为x,y,z表示[x,y]的和为z。如果当前区间和与前面的区间和发生冲突,当前区间和会被判错,问:有多少个区间和会被判错。

题解:x,y,z表示从x开始到y的所有数字的和,那么x-1就表示从(x-1,y]的区间和。我们可以对区间的左边x-1寻找他的左端点,同时对区间右边y也寻找他的左端点,如果这两个左端点相等(设为l)那么他就是将区间了[l,y]拆分成了[l,x-1]和[x,y],我们判断一下区间和是不是相等的就可以了也就是w[y]==w[x-1]+realtion。

如果左端点不相等的话,我们就进行合并。

(A和B分别为x和y的根节点)

合并后:

然后再修改权值, 规定B为A的父节点,也就是说现在这棵树B是根节点了,x到B的路径应该有两种,一种是x->A->B,权值之和为w[x]+AB,另外一种是x->y->b权值之和为relation+w[y]

二者应该相等,所以w[x]+AB=relation+w[y],所以AB=w[A]=w[y]-w[x]+relation。

code:

  

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7;
int fa[N];
int w[N];
int find(int x){
    if(x==fa[x]) return x;
    else {
        int c=find(fa[x]);
        w[x]+=w[fa[x]];
        return fa[x]=c;
    }
}
bool unite(int x,int y,int relation){
    int fx=find(x),fy=find(y);
    if(fx!=fy){
        fa[fy]=fx;
        w[fy]=w[x]-w[y]+relation;
        return 0;
    }
    else {
        return relation!=w[y]-w[x];
    }
}
int main(){
    int n,m;
    ios::sync_with_stdio(0);
    while(cin>>n>>m){
        for(int i=0;i<=n;i++) {
            fa[i]=i;
            w[i]=0;
        }
        int ans=0;
        for(int i=1;i<=m;i++){
            int x,y,z;
            cin>>x>>y>>z;
            x--;
            if(unite(x,y,z)) ans++;
        }
        cout<<ans<<endl;
    }
    return 0;
 } 

原文地址:https://www.cnblogs.com/Accepting/p/12643848.html

时间: 2024-10-10 14:23:56

How Many Answers Are Wrong HDU - 3038 (经典带权并查集)的相关文章

POJ 1984 Navigation Nightmare 【经典带权并查集】

任意门:http://poj.org/problem?id=1984 Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 7783   Accepted: 2801 Case Time Limit: 1000MS Description Farmer John's pastoral neighborhood has N farms (2 <= N <= 40,000), usuall

HDU3234&amp;&amp;UVA12232&amp;&amp;LA4487:Exclusive-OR(经典带权并查集)

Problem Description You are not given n non-negative integers X0, X1, ..., Xn-1 less than 220 , but they do exist, and their values never change. I'll gradually provide you some facts about them, and ask you some questions. There are two kinds of fac

poj1182食物链,经典带权并查集

动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类. 第二种说法是"2 X Y",表示X吃Y. 此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的.当一句话满足下列三条之一时,这句话就是假话,否

POJ 1182 食物链(经典带权并查集 向量思维模式 很重要)

传送门: http://poj.org/problem?id=1182 食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 90562   Accepted: 27216 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食

POJ1182 食物链(必做经典带权并查集)

  分析:   本题最重要的是通过向量的想法来解决这一类关系,这样思维难度大大降低,首先我们明白一点   根据传递性的定义(也就是离散数学中的传递性),x->y =x->z+z>y   我们要知道的一点是,并查集中的题目都是有传递性的,而传递性的题目并不一定能通过并查集解决   我们知道我们要将两个不同的集合合并,就是将他们的头结点合并,所以我们需要知道d[pa]的大小是多少   那么我们定义pa->pb的关系就等于 pa->x+x->y+y->pb,其中x-&g

HDU - 3038 How Many Answers Are Wrong (带权并查集)

题意:n个数,m次询问,每次问区间a到b之间的和为s,问有几次冲突 思路:带权并查集的应用,[a, b]和为s,所以a-1与b就可以确定一次关系,通过计算与根的距离可以判断出询问的正确性 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 200010; int f[MAXN],a

HDU 3038 How Many Answers Are Wrong (带权并查集+区间判断)

题意:给你长度为n的区间,m个询问:a,b,c,问这m个问题有多少个是错误的(矛盾). 10 5 1 10 100 7 10 28 1 3 32 4 6 41 6 6 1 由6->6=1,  4->6=41 知4->5=40; 同理 由1->10=100,7->10=28 知1->7=72; 又由1->3=32,4-6=41 知1->7=73,与上面矛盾: 所以答案为1: #include<cstdio> #include<stdlib.h

hdu 3038 How Many Answers Are Wrong【带权并查集】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3038 题意:给出两个数N和M代表有N个数个M组数据 N个数是未知的,然后M组数据每组数据形如:l r x 代表位置l和位置r之间的数的和为x,最后求出M组数据中有 几组是与上面冲突的. 分析:这道题我直接就知道是带权并查集的题,原因是我直接按带权并查 集找的题,所以在这不能为诸君讲述有此类题如何联系到并查集的过程. 直接说方法吧,首先定义数据level[maxn]存相权值初始化为0,level[x]

带权并查集(含种类并查集)【经典模板】 例题:①POJ 1182 食物链(经典)②HDU - 1829 A bug&#39;s life(简单) ③hihoCoder 1515 : 分数调查

带权并查集: 增加一个 value 值,并且每次合并和查找的时候需要去维护这个 value 例题一 :POJ 1182 食物链(经典) 题目链接:https://vjudge.net/contest/339425#problem/E 带权并查集的解法 定义两个数组fa[ ]和rela[ ],fa用来判断集合关系,rela用来描述其与根节点的关系.因为关系满足传递性,所以可以推导出给出条件下的当前关系,在判断与之前已有关系是否矛盾. 本题的解法巧妙地利用了模运算,rela数组用0表示同类,1表示当