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>
#include<string.h>
#include<string>
#include<map>
#include<cmath>
#include<iostream>
#include <queue>
#include <stack>
#include<algorithm>
#include<set>
using namespace std;
#define INF 1e8
#define eps 1e-8
#define LL long long
#define maxn 100001
#define PI acos(-1.0)

int father[2*maxn];
int sum[2*maxn];
int find(int x)
{
	if(x==father[x])
		return x;
	int t=father[x];
	father[x]=find(father[x]);
	sum[x]+=sum[t];
	return father[x];
}
int main()
{
	int n,m;
	while(~scanf("%d%d",&n,&m))
	{
		int a,b,c;
		for(int i=0;i<=n;i++)
		{
			father[i]=i;
			sum[i]=0;
		}
		int ans=0;
		while(m--)
		{
			scanf("%d%d%d",&a,&b,&c);
			int x,y;
			a--;
			x=find(a);
			y=find(b);
			if(x==y)
			{
				if(sum[a]-sum[b]!=c)
					ans++;
			}
			else if(x>y)
			{
				father[y]=x;
				sum[y]=sum[a]-sum[b]-c;
			}
			else
			{
				father[x]=y;
				sum[x]=sum[b]-sum[a]+c;
			}

		}
		printf("%d\n",ans);
	}
	return 0;
}
/*
10 5
1 10 100
7 10 28
1 3 32
4 6 41
6 6 1
*/

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

时间: 2024-08-07 16:58:54

HDU 3038 How Many Answers Are Wrong (带权并查集+区间判断)的相关文章

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

分析:这一题和HDU3047一样,都是带权并查集,求后输入和先输入的冲突个数 然后其实就是用并查集维护一棵树,小的作为大的祖先,然后这棵树每个节点到根的路径权值是相对根节点的距离 这样就可以维护距离限制,判断冲突 #include <cstdio> #include <cstring> #include <queue> #include <set> #include <map> #include <stack> #include &l

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

How Many Answers Are Wrong Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2961    Accepted Submission(s): 1149 Problem Description TT and FF are ... friends. Uh... very very good friends -_____

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

http://acm.hdu.edu.cn/showproblem.php?pid=3038 大致题意: 有一个区间[0,n],然后会给出你m个区间和,每次给出a,b,v,表示区间[a,b]的区间和为v,但每次给出的区间可能与之前的有冲突,问这样起冲突的区间共有多少个 首先区间[a,b]的和可由区间[0,b]的和减去区间[0,a-1]的和得到 但是我们不太可能知道[0,b],故我们只用知道和b的合并过的区间的左端点就行 其实并查集实质就是一颗树,我们可以以树的角度去看待它,理解维护过程 不理解的

HDU3038 How Many Answers Are Wrong[带权并查集]

How Many Answers Are Wrong Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6336    Accepted Submission(s): 2391 Problem Description TT and FF are ... friends. Uh... very very good friends -_____

hdu 3038 How Many Answers Are Wrong(种类并查集)

了解了种类并查集,同时还知道了一个小技巧,这道题就比较容易了. 其实这是我碰到的第一道种类并查集,实在不会,只好看着别人的代码写.最后半懂不懂的写完了.然后又和别人的代码进行比较,还是不懂,但还是交了. 现在回过头来看,又看了一遍. 题意—— 输入—— 给出多组测试数据. 每组数据第一行包含两个整数n, m.n表示共有1——n这么多个数,m表示m组提示. 接下来m行,每行包含三个整数a, b, val.表示从a到b这几个数的和为val. 这几组数有可能有冲突,问一共有多少组有冲突的数据. 输出—

HDU3038:How Many Answers Are Wrong(带权并查集)

How Many Answers Are Wrong Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 16338    Accepted Submission(s): 5724 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3038 Description: TT and FF are ..

HDU Virtual Friends(超级经典的带权并查集)

Virtual Friends Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11092    Accepted Submission(s): 3221 Problem Description These days, you can do all sorts of things online. For example, you can

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【带权并查集】

题目链接: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]