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:他吃根 ).当 ...
随机推荐
- JAVA常用的集合类
package com.xian.test; import java.util.ArrayList; import java.util.Enumeration; import java.util.Ha ...
- Web容器启动中执行某个Java类
1.监听(Listener) <!-- 配置监听 --> <listener> <listener-class>com.xian.jdbc.GetPropertie ...
- 夯实Java基础(二)——面向对象之封装
1.封装介绍 封装封装,见名知意,就是把东西包装隐藏起来,不被外界所看见, 而Java特性封装:是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数 ...
- PowerShell安装IIS
Windows作web开发的同学,应该都会用到IIS服务器.比如在阿里云或是Azure上购买一台新的服务器,默认是没有安装IIS的(安装的镜像就带有IIS或是MySql的除外).届时需要安装IIS,安 ...
- C++实现多组数据合并输出
思路 假设有多组数据,每一组都是按从小到大的顺序输入的,设计如下数据结构 前面一列是每一组数据的首部,后面是真正的数据,首部的定义为: struct head { Node* next; head* ...
- Notepad++编辑器——Verilog、代码片段、F6编译
Notepad++是一款精致小巧的编辑器,自带Verilog语法识别功能,插件也挺好用的.这里陈列一下我的设置. 版本:Notepad++ 7.6.6 ,32位 //================= ...
- 电脑查询pico的mac
配置好adb或者sdk后, adb shell cat /sys/class/net/wlan0/address
- 洛谷 P2024 [NOI2001]食物链
题意简述 有人用两种说法对这 N 个动物所构成的食物链关系进行描述: 1."1 X Y",表示 X 和 Y 是同类. 2."2 X Y",表示 X 吃 Y . ...
- Fabric项目学习总结
1.Hyperledger Fabric的基本架构 2.PKI机制
- Top 10 顶级项目管理工具
成功的项目都要归功于成功的项目管理.这些工具帮你踏上成功之旅! 项目管理是成功完成项目并使公司变得伟大的秘诀.不,这不是标题党(clickbait) -- 我已经看到两家软件公司(我在那里工作)因为项 ...