POJ 1182 食物链 [并查集 带权并查集 开拓思路]
Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u
System Crawler (2015-01-27)
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
先吐槽一下关于多组样例的问题,闲话也不多说,这题网上大牛各种神奇的题解都有,第一份代码是常规带权并查集的做法,不多谈,我主要想谈一下第二份代码的思路。
如果我们换一个思路,把1--n看成与自身同类的集合,1+n--2*n看成自己吃的集合,1+2*n--3*n看成吃自己的集合,那么问题便简单多了~~~
- #include<iostream>
- #include<cstring>
- #include<cstdlib>
- #include<cstdio>
- #include<algorithm>
- #include<cmath>
- #include<queue>
- #include<map>
- #include<set>
- #include<stack>
- #include<string>
- #define N 50005
- #define M 105
- #define mod 1000000007
- //#define p 10000007
- #define mod2 1000000000
- #define ll long long
- #define LL long long
- #define eps 1e-6
- #define inf 100000000
- #define maxi(a,b) (a)>(b)? (a) : (b)
- #define mini(a,b) (a)<(b)? (a) : (b)
- using namespace std;
- int n,m;
- int f[N];
- int r[N];
- int ans;
- void ini()
- {
- ans=;
- int i;
- for(i=;i<=n;i++){
- f[i]=i;
- r[i]=;
- }
- }
- int find(int x)
- {
- int fa;
- if(f[x]!=x)
- {
- fa=find(f[x]);
- r[x]=(r[x]+r[ f[x] ])%;
- f[x]=fa;
- }
- return f[x];
- }
- void merge(int x,int y,int d)
- {
- int a,b;
- a=find(x);
- b=find(y);
- if(a==b){
- return;
- }
- f[b]=a;
- r[b]=(-r[y]+r[x]+d)%;
- }
- void solve()
- {
- int d,x,y;
- int a,b;
- int re;
- int i;
- for(i=;i<=m;i++){
- scanf("%d%d%d",&d,&x,&y);
- if(x>n || y>n){
- ans++;continue;
- }
- if(d== && x==y){
- ans++;continue;
- }
- a=find(x);
- b=find(y);
- re=(-r[x]+r[y])%;
- if(a==b && re!=d-){
- ans++;continue;
- }
- //printf(" i=%d\n",i);
- merge(x,y,d-);
- }
- }
- void out()
- {
- printf("%d\n",ans);
- }
- int main()
- {
- //freopen("data.in","r",stdin);
- //freopen("data.out","w",stdout);
- //scanf("%d",&T);
- //for(int ccnt=1;ccnt<=T;ccnt++)
- //while(T--)
- //while(scanf("%d%d",&n,&m)!=EOF)
- scanf("%d%d",&n,&m);
- {
- ini();
- solve();
- out();
- }
- return ;
- }
如果我们换一个思路,把1--n看成与自身同类的集合,1+n--2*n看成自己吃的集合,1+2*n--3*n看成吃自己的集合,那么问题便简单多了~~~
- #include<iostream>
- #include<cstring>
- #include<cstdlib>
- #include<cstdio>
- #include<algorithm>
- #include<cmath>
- #include<queue>
- #include<map>
- #include<set>
- #include<stack>
- #include<string>
- #define N 50005
- #define M 105
- #define mod 1000000007
- //#define p 10000007
- #define mod2 1000000000
- #define ll long long
- #define LL long long
- #define eps 1e-6
- #define inf 100000000
- #define maxi(a,b) (a)>(b)? (a) : (b)
- #define mini(a,b) (a)<(b)? (a) : (b)
- using namespace std;
- int n,m;
- int f[*N];
- int ans;
- void ini()
- {
- ans=;
- int i;
- for(i=;i<=*n;i++){
- f[i]=i;
- }
- }
- int find(int x)
- {
- int fa;
- if(f[x]!=x)
- {
- fa=find(f[x]);
- f[x]=fa;
- }
- return f[x];
- }
- void merge(int x,int y)
- {
- int a,b;
- a=find(x);
- b=find(y);
- if(a==b){
- return;
- }
- f[b]=a;
- }
- void solve()
- {
- int d,x,y;
- int a,b;
- int fx,sx;
- int i;
- for(i=;i<=m;i++){
- scanf("%d%d%d",&d,&x,&y);
- if(x>n || y>n){
- ans++;continue;
- }
- if(d== && x==y){
- ans++;continue;
- }
- a=find(x);
- b=find(y);
- fx=find(x+n);
- sx=find(x+*n);
- if(d==){
- if(b==fx || b==sx){
- ans++;continue;
- }
- else{
- merge(x,y);
- merge(x+n,y+n);
- merge(x+*n,y+*n);
- }
- }
- else{
- if(b==a || b==sx){
- ans++;continue;
- }
- else{
- merge(x+n,y);
- merge(x+*n,y+n);
- merge(x,y+*n);
- }
- }
- }
- }
- void out()
- {
- printf("%d\n",ans);
- }
- int main()
- {
- //freopen("data.in","r",stdin);
- //freopen("data.out","w",stdout);
- //scanf("%d",&T);
- //for(int ccnt=1;ccnt<=T;ccnt++)
- //while(T--)
- //while(scanf("%d%d",&n,&m)!=EOF)
- scanf("%d%d",&n,&m);
- {
- ini();
- solve();
- out();
- }
- return ;
- }
POJ 1182 食物链 [并查集 带权并查集 开拓思路]的更多相关文章
- poj 1182 食物链(高级的带权并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 76486 Accepted: 22742 Description ...
- 浅谈并查集&种类并查集&带权并查集
并查集&种类并查集&带权并查集 前言: 因为是学习记录,所以知识讲解+例题推荐+练习题解都是放在一起的qvq 目录 并查集基础知识 并查集基础题目 种类并查集知识 种类并查集题目 并查 ...
- 【POJ 1984】Navigation Nightmare(带权并查集)
Navigation Nightmare Description Farmer John's pastoral neighborhood has N farms (2 <= N <= 40 ...
- Poj1182 食物链(并查集/带权并查集)
题面 Poj 题解 这里采用并查集的补集. \(x\)表示同类集合,\(x+n\)表示敌人集合,\(x+n\times2\)表示敌人的敌人集合. 如果当前给出的是一对同类关系,就判断\(x\)是否吃\ ...
- POJ 1984 Navigation Nightmare 【经典带权并查集】
任意门:http://poj.org/problem?id=1984 Navigation Nightmare Time Limit: 2000MS Memory Limit: 30000K To ...
- [poj 2912] Rochambeau 解题报告 (带权并查集)
题目链接:http://poj.org/problem?id=2912 题目: 题目大意: n个人进行m轮剪刀石头布游戏(0<n<=500,0<=m<=2000) 接下来m行形 ...
- poj 1733 Parity game【hash+带权并查集】
hash一下然后用带权并查集做模2下的前缀和 #include<iostream> #include<cstdio> #include<map> #include& ...
- POJ 2492 A Bug's Life 带权并查集
题意: 思路: mod2 意义下的带权并查集 如果两只虫子是异性恋,它们的距离应该是1. 如果两只虫子相恋且距离为零,则它们是同性恋. (出题人好猥琐啊) 注意: 不能输入一半就break出来.... ...
- POJ 2492 A Bug's Life (带权并查集 && 向量偏移)
题意 : 给你 n 只虫且性别只有公母, 接下来给出 m 个关系, 这 m 个关系中都是代表这两只虫能够交配, 就是默认异性, 问你在给出的关系中有没有与异性交配这一事实相反的, 即同性之间给出了交配 ...
随机推荐
- Maven项目报错:Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:2.5:clean (default-clea
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:2.5:clean (default-clean) ...
- jni 开发
创建android工程 -> 添加native 函数 添加库之后: 1. 用javah 生成c语言.h头文件时, 在cmd 窗口中cd 到bin/classes 目录下执行下代码无效: java ...
- python基础一 day14 复习
迭代器和生成器迭代器:双下方法 : 很少直接调用的方法.一般情况下,是通过其他语法触发的可迭代的 —— 可迭代协议 含有__iter__的方法('__iter__' in dir(数据))可迭代的一定 ...
- 关于POST的请求的问题的汇总
1)404 解决方式:检查路径,路由问题 2)500 解决方式:1)首先检查代码 2)检查是否是参数未接收到 3)检查是否Content-Type类型导致的参数未收到 4)区分body-raw跟bod ...
- 转义字符 & sizeof & strlen
在定义了数组大小时: sizeof是运算符,表示编译时分配的空间大小,即数组定义的大小,char t[20] = "sfa".sizeof: 20; strlen: 3.在未定义数 ...
- java在线聊天项目1.0版 异常处理——开启多个客户端,关闭一个客户端后,在其他客户端中再发出信息会出现异常的处理
异常一 只开启一个客户端,输入信息后关闭,客户端出现如下异常 根据异常说明 ChatClientFrame客户端117行 提示原因是Socket关闭 分析原因 客户端代码 while (connect ...
- mac系统快捷键大全详细介绍(全部)
对于使用苹果电脑的操作系统的新人来说,快捷键是个很麻烦的问题,要一个个的找到快捷键也不是很容易的问题,今天这篇文章就解决了到处找快捷键的麻烦. 第一种分类:启用快捷键 按下按键或组合键,直到所需的功能 ...
- XCode和Cocoa在开发中使用第三方dylib示例
XCode和Cocoa在开发中使用第三方dylib示例 www.educity.cn 发布者:yukowang 来源:网络转载 发布日期:2014年06月13日 XCode和Co ...
- django-ckeditor添加代码功能(codesnippet)
最近做了一个博客,使用python3+django2.1开发的,后台编辑器和前端显示用的Django-ckeditor富文本编辑器,由于发现没有代码块功能,写上去的代码在前端展示有点乱,于是一顿问度娘 ...
- 【OS_Linux】Linux 基本命令整理
1. 查看目录文件:ls2. 打印当前工作目录:pwd3. 查看文件内容:cat 文件名4. 打开编辑器:vim 文件名 1 2 3 4 5 修改:按Insert键 退出修改模式:按Esc 键 进入输 ...