How Many Answers Are Wrong (HDU - 3038)(带权并查集)
并查集是用来对集合合并查询的一种数据结构,或者判断是不是一个集合,本题是给你一系列区间和,判断给出的区间中有几个是不合法的。
思考:
1.如何建立区间之间的联系
2.如何发现悖论
首先是如何建立联系,我们可以用一张图表示

假如说区间【fx,x】是之前建立的区间,他们之间和为sum[x],fx和x的联系可以用集合来存储,同理【fy,y】也是如此。当给出了一个新的区间【x,y】时,且区间和为s。
就产生了两种情况了,如果fx == fy 那么这两个区间是有关联的区间,也就是【x,y】之间的和是可以求出的。可以把这个图看成一个向量。
区间【x,y】的和就是可以写成sum[x] - sum[y]。
判断给出的s与向量法计算的区间和是否相等就可以判断是否是悖论。
当然如果fx != fy就需要建议新的区间关系。首先将fy指向fx,这代表fx是区间的左端点,计算sum【fy】= sum【x】- sum【y】+ s;这里同样用的是向量法。
这样建立联系与判断悖论都可以表达了,接下来就是一些细节了,比如在更新区间的时候要进行路径的压缩,压缩的过程中需要对权值进行更新,目的是使每个已知区间最大化。
解题思路:这个题乍一看可能要线段树或树状数组,其实没有必要,区间和可以理解为前缀和相减。
每个节点记录前缀和,对每个询问先判断两个节点是否连通,这便是带权并查集干的事了,若联通则权值相减看是否为给定值,若不为则矛盾;若不联通则两棵树合并为一棵(注意有顺序)同时计算出新的子节点的权值。
AC代码
#include<bits/stdc++.h>
using namespace std; const int maxn = + ; int pre[maxn] ,sum[maxn];//sum是该节点到其根的和,如sum【3】
//,3的根是1,就是1到3的和 int find(int x){
if(x == pre[x]) return x;
else { int root = find(pre[x]);
sum[x] += sum[pre[x]];
return pre[x] = root;
}
} void init(int n){
for(int i = ; i <= n;i++){
pre[i] = i;
sum[i] = ;
}
}
int ans = ;
void unions(int x,int y,int s){
int fx = find(x);
int fy = find(y);
if(fx != fy){
pre[fy] = fx;
sum[fy] = sum[x] - sum[y] + s;
}
else if(sum[y] - sum[x] != s)
ans ++; }
int main(){
int n,m;
//cin >> n >> m;
while(cin >> n >> m){
init(n);
int x,y;
int s;
ans = ;
while(m--){
cin >> x >> y >> s;
x --;
unions(x,y,s);
} cout << ans << endl;
} return ;
}
How Many Answers Are Wrong (HDU - 3038)(带权并查集)的更多相关文章
- HDU - 3038 带权并查集
这道题我拖了有8个月... 今天放假拉出来研究一下带权的正确性,还有半开半闭的处理还有ab指向的一系列细节问题 #include<iostream> #include<algorit ...
- hdu 3038带权并查集
#include<stdio.h> #include<string.h> #define N 200100 struct node { int x,count; }pre[N ...
- HDU 3038 How Many Answers Are Wrong 【YY && 带权并查集】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=3038 How Many Answers Are Wrong Time Limit: 2000/1000 ...
- hdu 1829 带权并查集的运用类似于食物链但是更简单些
#include<stdio.h> #define N 1100000 struct node { int x,y; }f[N],pre[N]; int find(int x) { if( ...
- Zjnu Stadium HDU - 3047 带权并查集板子题
#include<iostream> #include<cstring> #include<cstdio> using namespace std; +; int ...
- HDU 3038 - How Many Answers Are Wrong - [经典带权并查集]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3038 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
- HDU - 3038 How Many Answers Are Wrong (带权并查集)
题意:n个数,m次询问,每次问区间a到b之间的和为s,问有几次冲突 思路:带权并查集的应用.[a, b]和为s,所以a-1与b就能够确定一次关系.通过计算与根的距离能够推断出询问的正确性 #inclu ...
- hdu 3038 How Many Answers Are Wrong【带权并查集】
带权并查集,设f[x]为x的父亲,s[x]为sum[x]-sum[fx],路径压缩的时候记得改s #include<iostream> #include<cstdio> usi ...
- HDU3038 How Many Answers Are Wrong —— 带权并查集
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3038 How Many Answers Are Wrong Time Limit: 200 ...
随机推荐
- Raven2
Raven2实验 0x01 寻找IP 本机IP:56.130 1. 使用 nmap -sn "ip6"#主机发现(不进行端口扫描) https://cloud.tencent.c ...
- Java版基于SpringBoot+Vue.js实现自动创表自动定时采集(各个微信公众号商城产品进行采集)-爬虫篇
- MT41J256M16HA-125 原厂订购 现货销售
作为一家科研公司,保证芯片的原厂品质和正规采购渠道是科学严谨的研发工作中重要的一环,更是保证研发产品可靠.稳定的基础.而研发中所遇到的各种不可预测的情况更是每个工程师向技术的山峰攀登中时会遇到的各种难 ...
- Linux性能优化从入门到实战:01 Linux性能优化学习路线
我通过阅读各种相关书籍,从操作系统原理.到 Linux内核,再到硬件驱动程序等等. 把观察到的性能问题跟系统原理关联起来,特别是把系统从应用程序.库函数.系统调用.再到内核和硬件等不同的层级贯 ...
- qt 视频播放
可以播出视频,待完善 player = new QMediaPlayer(this); playlist = new QMediaPlaylist(); playlist->addMedia(Q ...
- 详解zabbix中文版安装部署
一.zabbix简介(摘自百度百科) zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案. zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供柔软 ...
- 使用django 的cache设置token的有效期
from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import A ...
- LeetCode--058--最后一个单词(java)
给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度. 如果不存在最后一个单词,请返回 0 . 说明:一个单词是指由字母组成,但不包含任何空格的字符串. 示例: 输入: &quo ...
- git怎样删除未监视的文件untracked files ?
git怎样删除未监视的文件untracked files 需要添加到.gitignore文件 # 删除 untracked files git clean -f # 连 untracked 的目录也一 ...
- 【HDOJ6687】Rikka with Stable Marriage(Trie树,贪心)
题意:给定两个长均为n的序列a和b,要求两两配对,a[i]和b[j]配对的值为a[i]^b[j],求配对后的值之和的最大值 n<=1e5,a[i],b[i]<=1e9 思路:和字典序最大的 ...