POJ 1182 食物链(经典并查集) (多组输入有时乱加也会错!)
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 68854 | Accepted: 20363 |
Description
现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。
有人用两种说法对这N个动物所构成的食物链关系进行描述:
第一种说法是"1 X Y",表示X和Y是同类。
第二种说法是"2 X Y",表示X吃Y。
此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
1) 当前的话与前面的某些真的话冲突,就是假话;
2) 当前的话中X或Y比N大,就是假话;
3) 当前的话表示X吃X,就是假话。
你的任务是根据给定的N(1 <= N <= 50,000)和K句话(0 <= K <= 100,000),输出假话的总数。
Input
以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。
若D=1,则表示X和Y是同类。
若D=2,则表示X吃Y。
Output
Sample Input
100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5
Sample Output
3
Source
题意:一共就三种动物,如果A吃B,B吃C==》C吃A;
A吃B,A吃C==》B、C为同类
A被B吃,A被C吃==》B、C为同类
用并查集来做:
两种动物之间的关系通过于根节点的相对关系得出,所以关键是路径压缩与合并两个集合时的动物与根节点相对关系的变化,其实也可认为是一个问题,因为路径压缩中的变化其实是合并集合产生的子问题。
用delta【i】来表示i和i的父节点的关系,rank[i]=0/1/2分别表示 i 与父亲是同类、被父亲吃、吃父亲。
先讲合并操作:
设tx为x的父亲,ty是y的父亲,所以delta[x]表示x和tx的关系,delta[y]表示y与ty的关系,现在,合并操作要将ty的父亲置为tx,所以delta[ty]的值就要发生相应的改变,即产生了新的ty与tx的关系;
那么,如何求这个关系呢?有两种方法:第一种,可以通过实际数据推出来,
tx ty
| |
x ~ y
知道了tx与x的关系,x与y的关系,y与ty的关系,tx与ty的关系自然就推出来了
type表示x与y的关系0为同类,1为x吃y
| type | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | ||||||||||
| delta[x] | 0 | 0 | 0 | 1 | 0 | 1 | 2 | 2 | 1 | ||||||||||
| delta[y] | 0 | 1 |
2 |
2 | 2 | 2 | 1 | 2 | 1 | ||||||||||
| delta[ty] | 0 | 2 | 1 | 2 | 2 | 0 | 2 | 1 | 1 |
仔细再想想,tx-x 、x-y、y-ty,是不是很像向量形式,于是便有了一般化的结论:来自北大discuss
tx ty
| |
x ~ y
对于集合里的任意两个元素x,y而言,它们之间必定存在着某种联系,
因为并查集中的元素均是有联系的,否则也不会被合并到当前集合中。那么我们
就把这2个元素之间的关系量转化为一个偏移量,以食物链的关系而言,不妨假设
x->y 偏移量0时 x和y同类
x->y 偏移量1时 x吃y
x->y 偏移量2时 x被y吃,也就是y吃x
有了这些基础,我们就可以在并查集中完成任意两个元素之间的关系转换了。
不妨继续假设,x的当前集合根节点tx,y的当前集合根节点ty,x->y的偏移值为d-1(题中给出的询问已知条件)
(1)如果tx和ty不相同,那么我们把ty合并到tx上,并且更新deltx[ty]值(注意:deltx[i]表示i的当前集合根节点到i的偏移量!!!!)
此时 tx->ty = tx->x + x->y + y->ty,可能这一步就是所谓向量思维模式吧
上式进一步转化为:tx->ty = (deltx[x]+d-1+3-deltx[y])%3 = deltx[ty],(模3是保证偏移量取值始终在[0,2]间)
(2)如果tx和ty相同,那么我们就验证x->y之间的偏移量是否与题中给出的d-1一致
此时 x->y = x->tx + tx->y = x->tx + ty->y,
上式进一步转化为:x->y = (3-deltx[x]+deltx[y])%3,
若一致则为真,否则为假。
牛的想法啊!
凡人就模仿着学习啦~哈哈
接下来把这个想法再运用到路径压缩中:
ffx
| \
fx \
| /
| /
x
路径压缩过程中会将fx的父亲变为x的父亲,所以要改变相对关系,即偏移量。
ffx->fx+fx->x=ffx->x;
转换成:delta[x]=(delta[fx]+delta[x])%3;
下面是个人理解
这道题目的大概意思是先用t[]来存下两个动物之间的关系,0代表x和y是同类,1代表x吃y,2代表x被y吃
题目输入的是1,2,所以加入join时要type-1,大的else是用来跟新t[ty]的
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int pre[],t[],n;
int find(int x)
{
if(x==pre[x])
return x;
int tx=find(pre[x]);
t[x]=(t[x]+t[pre[x]])%;//关键,跟新路径
return pre[x]=tx;
}
int join(int x,int y,int type)
{
if(x>n||y>n)
return ;
if(type==&&x==y)
return ;
int tx=find(x);
int ty=find(y);
if(tx==ty)
{
if((t[y]-t[x]+)%!=type)
return ;
else return ;
}
else
{
pre[ty]=tx;
t[ty]=(t[x]-t[y]+type+)%;//关键,加3为了防止负数的出现!!!
return ;
}
}
int main()
{
int type;
int num,x,y,k;
while(~scanf("%d%d",&n,&k))
{
num = ;
for(int i=;i<=n;i++)
{
pre[i] = i;
t[i] = ;
}
while(k--)
{
scanf("%d%d%d",&type,&x,&y);
if(join(x,y,type-))
num++;
}
printf("%d\n",num);
}
return ;
}
POJ 1182 食物链(经典并查集) (多组输入有时乱加也会错!)的更多相关文章
- POJ 1182 食物链 经典并查集+关系向量简单介绍
题目: 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有 ...
- poj 1182 食物链 (并查集)
http://poj.org/problem?id=1182 关于并查集 很好的一道题,开始也看了一直没懂.这次是因为<挑战程序设计竞赛>书上有讲解看了几遍终于懂了.是一种很好的思路,跟网 ...
- POJ 1182 食物链(并查集拆点)
[题目链接] http://poj.org/problem?id=1182 [题目大意] 草原上有三种物种,分别为A,B,C A吃B,B吃C,C吃A. 1 x y表示x和y是同类,2 x y表示x吃y ...
- POJ 1182 食物链(并查集+偏移向量)题解
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 82346 Accepted: 24616 Description ...
- POJ 1182 食物链 (并查集解法)(详细注释)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 78510 Accepted: 23396 Description ...
- POJ 1182 食物链(种类并查集)
记得第一次做这道题的时候,推关系感觉有点复杂,而且写完代码后一直WA,始终找不出错误. 在A了十几道并查集后,再做这道题,发现太小儿科了.发现原来之所以WA,就在于查找根节点时,没有同步更新子节点相对 ...
- 【POJ 1182 食物链】并查集
此题按照<挑战程序设计竞赛(第2版)>P89的解法,不容易想到,但想清楚了代码还是比较直观的. 并查集模板(包含了记录高度的rank数组和查询时状态压缩) *; int par[MAX_N ...
- POJ 1182 食物链 【并查集】
解题思路:首先是没有思路的----然后看了几篇解题报告 http://blog.csdn.net/ditian1027/article/details/20804911 http://poj.org/ ...
- poj 1182食物链(并查集)
算法思路:把那些确定了相对关系的节点放在同一棵树里(可以同时存在多棵树,单独每棵树中节点的相对关系确定),每个节点对应的 v[] 值记录他与根节点的关系( 0:同类: 1:根吃他: 2:他吃根 ).当 ...
随机推荐
- Android UI绘制流程及原理
一.绘制流程源码路径 1.Activity加载ViewRootImpl ActivityThread.handleResumeActivity() --> WindowManagerImpl.a ...
- 2019中山纪念中学夏令营-Day9[JZOJ](第六次模拟赛)
Begin (题目的排序方式:Unkown其实是按心情排的) 异或:(摘自百度百科) 异或(xor)是一个数学运算符.它应用于逻辑运算.异或的数学符号为“⊕”,计算机符号为“xor”.其运算法则为: ...
- JAVA基础知识(八)值传递与引用传递
值传递:(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数值的改变不影响 ...
- MyEclipse下安装FreeMark插件
现在大多人人喜欢用FreeMark模板.但是这个模板在myeclipse或者是eclipse下却是不能只能提示,一大堆只是没有颜色区分的显示在哪里.万能天国总是有办法. 点我去官网下载(比较慢) 我的 ...
- python基础知识 01
一.计算机基础知识 计算机有硬件+操作系统+软件应用组成 cpu:人的大脑 内存:人的临时记忆 硬盘:人的永久记忆 操作系统 控制计算机硬件工作的流程 应用程序 安装在操作系统上的软件 二.Pytho ...
- (一)c#Winform自定义控件-基类控件
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- 帝国CMS(EmpireCMS) v7.5 前台XSS漏洞分析
帝国CMS(EmpireCMS) v7.5 前台XSS漏洞分析 一.漏洞描述 该漏洞是由于javascript获取url的参数,没有经过任何过滤,直接当作a标签和img标签的href属性和src属性输 ...
- 如果有人问你 Dubbo 中注册中心工作原理,就把这篇文章给他
注册中心作用 开篇首先想思考一个问题,没有注册中心 Dubbo 还能玩下去吗? 当然可以,只要知道服务提供者地址相关信息,消费者配置之后就可以调用.如果只有几个服务,这么玩当然没问题.但是生产服务动辄 ...
- spring-boot-plus快速开始 Quick Start(一)
spring-boot-plus快速开始 Quick Start 1. clone项目到本地 shell script git clone git@github.com:geekidea/spring ...
- 对微软的敌视何时休? 从一篇语言评论文章对C#的评价说起
看到一篇公众号文章<2020年什么编程语言最受欢迎,待遇最高?>,其中对C#的描述如下: 点击阅读原文,看到这是一篇翻译文章:https://codinginfinite.com/top- ...