*hdu3038 (带权值并查集)
来源:互联网 发布:owncloud数据库配置 编辑:程序博客网 时间:2024/05/23 01:18
题目大意:有n次询问,给出a到b区间的总和,问这n次给出的总和中有几次是和前面已近给出的是矛盾的??
思路:如果我们知道a到b之间的关系,a到c之间的关系,那么我们就可以知道a,b,c任意两个之间的关系,如果我们再知道了d和c之间的关系,那么我们就知道了a,b,c,d之间的关系,但是怎么表示这些关系呢??我们用的是并查集,顺便加一个每一个节点到根的距离,这样的话,任意两个点之间关系就可以通过求与根的距离求差得出,也就是说,如果输入的n,m在一个集合里,那么我们判断这两个的关系是否和已有的冲突,如果n,m不在一个集合里,那么我们就合并这两个集合,是的n,m这两个所在的两个集合之间的任意元素都有关系。这里由于给出的数据不能合并,我们需要优化一下(a-1,b),例:给出(1,5)(6,7);我们知道这两个可以合并,但5和6不相等,我们就需要优化成(0,5)(5,7)这样就可以了;
代码:
#include<stdio.h>#include<string.h>int d[200005],sum[200005];int find(int tt){ if(tt==d[tt]) return tt; int t=d[tt]; d[tt]=find(d[tt]); sum[tt]=sum[tt]+sum[t]; //每次搜索根节点时,记录起点到根的距离; return d[tt];}void sort(int a,int b,int zx,int zy,int c){ //我们要将大的设根节点 if(zx>zy) { d[zy]=zx;//设置zx为已给出数据的根; sum[zy]=sum[a]-c-sum[b]; zy到根节点的距离; } else { d[zx]=zy; sum[zx]=sum[b]+c-sum[a]; }}int main(){ int n,m; while(~scanf("%d%d",&n,&m)) { int i,s=0; for(i=0;i<=n;i++) d[i]=i; memset(sum,0,sizeof(sum)); for(i=1;i<=m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); a--; //优化 int zx=find(a); //寻找a的根节点,并且求出sum[a],即a到根的距离 int zy=find(b); if(zx==zy&&sum[a]!=sum[b]+c)//由于zx=zy,所以zx与zy根节点相同,就可以判断sum[a]是否等于sum[b]+c; { s++; } else if(zx!=zy) sort(a,b,zx,zy,c); } printf("%d\n",s); }}
0 0
- *hdu3038 (带权值并查集)
- hdu3038(并查集)
- hdu3038-并查集
- hdu3038(加权并查集)
- hdu3038(加权并查集)
- hdu3038之并查集
- 【HDU3038】【加权并查集】
- HDU3038【种类并查集】
- hdu3038,3047(带权并查集)
- 带权并查集 hdu3038
- hdu3038带权并查集
- HDU3038~How Many Answers Are Wrongc(带权并查集)
- hdu3038 How Many Answers Are Wrong --- 种类并查集
- Hdu3038 - How Many Answers Are Wrong - 并查集
- HDU3234Exclusive-OR(并查集)与HDU3038相似
- HDU3038 How Many Answers Are Wrong 【并查集】
- 并查集 hdu3038 How Many Answers Are Wrong
- hdu3038 How Many Answers Are Wrong--种类并查集
- 【Android】Android Studio 1.5+ 中混合调试Native和Java代码
- Linux下常用基本命令_文件搜索
- Git基本操作指南
- CF#243 C. Magic Formulas- xor异或运算 / 数学
- java多线程同步案列---按照固定格式输出数字和字母
- *hdu3038 (带权值并查集)
- 癌症有克星了吗?
- 关于Java类的一些思考
- Spring事务管理(详解+实例)
- 转载的一篇资讯
- UESTC 250 windy数 (数位DP)
- android中ListView控件&&onItemClick点击事件
- 欢迎使用CSDN-markdown编辑器
- Java线程