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

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=3038

根据前面的回答判断下一个回答是否矛盾,因为判断下一个回答要根据前面的回答,所以用并查集来记录前面数之间的关系,如果根据前面数的关系不能判断出这组数据的答案,那就把这组数据也加入到并查集里,如果能判断出答案,但是答案错误,那么res++,下面举一个栗子
在这里插入图片描述
如果我在前面有输入a,c和a,b之间的关系,在这一组数据中输入了b,c的关系,用V(a,b)代表a,b之间的距离,那么就有V(a,c)-V(a,b)==V(b,c),如果不符合,res++
输入三个数digit1,digit2,distance,就是[digit1,digit2]的和为distance,可以理解为digit2比(digit1-1)这个数大distance,用sum数组来储存权值"distance",这里就有sum[digit1-1]=distance。
但是在并查集查找的时候,不但要做路径压缩,压缩的同时还要维护权值数组sum的值,这里要用到向量的知识。举个例子,digit1的祖先是x,digit2的祖先是y,这里默认并查集合并时,x并到y上,但是光并上去不行啊,还得计算sum[x]的值,如何计算?看下面一张图
在这里插入图片描述
在查找d1和d2的祖先的过程中,我们肯定知道[d1,x]和[d2,y]的权值,为什么要合并x和y?出现这种情况就是因为输入给出了d1,d2之间的关系,而且这种关系无法判断真假,按真处理,加入并查集,那么如何计算sum[x]?这时候就很明显了,sum[x]就是[x,y]的和,通过向量,仍用V(a,b)来表示[a,b]之间的权值,V(x,y)=V(d2,y)+V(d1,d2)-V(d1,x)。
在d1,d2祖先相同的时候,如何判断他们的权值V(d1,d2)是否正确呢?也是这个道理,看下面一张图,因为他们有公共祖先,证明他们的sum值肯定在查找祖先的过程中经过了维护,直接指向了y(这里假设y为公共祖先),就有
V(D1,y)-V(D2,y)==V(D1,D2),V(D1,D2)的值会在这组输入数据中给出,根据这个进行判断即可。
在这里插入图片描述

C

#include <stdio.h>	
#include <string.h>
#pragma warning(disable:4996)
int tree[200001],sum[200001];
int get(int digit)
{
	int root;
	if(tree[digit]==digit)
		return digit;
	root=get(tree[digit]);
	sum[digit]+=sum[tree[digit]];
	return tree[digit]=root;
}
int main(void)
{
	int N,M,i,res,digit1,digit2,distance,x,y;
	while(scanf("%d %d",&N,&M)!=EOF)
	{
		memset(sum,0,sizeof(sum));
		for(i=0;i<=N;i++)	//注意这里的初始化,要从0开始,因为下面有digit1--,这里卡了我1小时WA
			tree[i]=i;		
		for(res=0,i=0;i<M;i++)
		{
			scanf("%d %d %d",&digit1,&digit2,&distance);
			digit1--;//注意这里,[d1,d2]的距离可以理解为d2比d1-1这个数大distance
			x=get(digit1);
			y=get(digit2);
			if(x!=y)	//如果祖先不相同,无法判断,一律按正确处理,并入并查集,我这里以默认x是y的后代,如果y是x的后代,向量计算将会改变,要注意表达式的变化
			{
				tree[x]=y;
				sum[x]=distance+sum[digit2]-sum[digit1];
			}
			else
				if(sum[digit1]-sum[digit2]!=distance)
					res++;
		}
		printf("%d\n",res);
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值