POJ 1182 并查集
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
#include <iostream>
#include<cstdio>
#include<string.h>
using namespace std;
const int maxn=;
int per[maxn],p[maxn],v[maxn],N,K;
int fa(int a){ return per[a]=per[a]==a?a:fa(per[a]);}
bool jud1(int X,int Y){
if(X<||Y<||X>N||Y>N) return false;
int fx=fa(X),fy=fa(Y);
if(fx==p[fy]||fx==v[fy]||fy==p[fx]||fy==v[fx]) return false;
per[fy]=fx;
if(p[fx]!=&&p[fy]!=){ per[p[fy]]=p[fx];}
if(p[fx]==&&p[fy]!=)p[fx]=p[fy];
if(v[fx]!=&&v[fy]!=){ per[v[fy]]=v[fx];}
if(v[fx]==&&v[fy]!=) v[fx]=v[fy];
if(p[fx]!=){ p[p[fx]]=v[fx]; v[p[fx]]=fx; }
if(v[fx]!=){ p[v[fx]]=fx; v[v[fx]]=p[fx];}
return true;
}
bool jud2(int X,int Y){
if(X<||Y<||X>N||Y>N) return false;
int fx=fa(X),fy=fa(Y);
if(fx==fy||fx==v[fy]||fy==p[fx]) return false;
if(p[fy]!=)per[p[fy]]=fx;
if(v[fx]==)v[fx]=fy;
else per[fy]=v[fx];
if(p[fx]!=&&v[fy]!=) per[v[fy]]=p[fx];
if(p[fx]==&&v[fy]!=) p[fx]=v[fy];
if(p[fx]!=){ v[p[fx]]=fx;p[p[fx]]=v[fx];}
if(v[fx]!=){ p[v[fx]]=fx;v[v[fx]]=p[fx];} return true;
}
int main()
{
scanf("%d%d",&N,&K);
for(int i=;i<=N;i++){
per[i]=i; p[i]=v[i]=;
}
int num=;
for(int i=;i<K;i++){
int D,X,Y;
scanf("%d%d%d",&D,&X,&Y);
switch(D){
case : if(jud1(X,Y)==false) ++num; break;
case : if(jud2(X,Y)==false) ++num; break;
}
}
cout<<num<<endl; return ;
}
还有一种方法 带权并查集 队友说也可以
当 操作1 时 判断
1 这两个点在 同一个集合当中 他们到达 祖先的距离不同则出现错误 相同就正确
2 这两个点不在同一个集合当中 那么就得将这两个集合 合并 就是说 d[x]=(d[y]+d[fy])%3或者 d[y]=(d[x]+d[fx])%3 这样就保证了他们在一个集合当中的相同的位置 我们在并查集中做了一点小动作 保证了要修改的 d[fx] 或者d[fy] 为跟节点的子树 能够将相应的位置进行相应的改变
当操作2 时 判断
1 这两个的点在同一个集合当中 他们到达祖先的距离(d[x]+1)必须等于d[y] 否则就出现错误(因为我们保证了小的距离吃大的距离 自然最后记得模三)
2 这两个点在不懂得集合当中 那么也必须得河滨这两个集合 就是说 (d[x]+1)%3==(d[y]+d[fy])%3 可以推得 (d[x]+1-d[y]+3)==d[fy] 这样也保证了这两个点在相对的位置
#include <iostream>
#include<cstdio>
#include<string.h>
using namespace std;
const int maxn=;
int per[maxn],d[maxn];
int fin(int a){
if(per[a]==a)return a;
int t=per[a];
per[a]=fin(per[a]);
d[a]=(d[a]+d[t])%;
return per[a];
}
bool unionnode(int D,int x,int y){
int fx=fin(x),fy=fin(y);
if(D==){
if(fx==fy){ return d[x]==d[y]?true:false; }
if(d[x]==d[y]){ per[fy]=fx;return true;}
if(d[x]>d[y]){ d[fy]=(d[x]-d[y])%;per[fy]=fx; return true; }
d[fx]=(d[y]-d[x])%; per[fx]=fy; return true;
}
if(fx==fy){ return ((d[x]+)%)==d[y]?true:false; }
d[fy]=(d[x]-d[y]++)%;
per[fy]=fx;
return true;
}
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++){
per[i]=i;d[i]=;
}
int num=;
while(k--){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(b>n||c>n||!unionnode(a,b,c)) num++;
}
printf("%d\n",num);
return ;
}
POJ 1182 并查集的更多相关文章
- POJ1703 && POJ2942 &&POJ 1182 并查集 这个做法挺巧妙
Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 37242 Accepted: ...
- 食物链 POJ - 1182 (并查集的两种写法)
这是一个非常经典的带权并查集,有两种写法. 1 边权并查集 规定一下,当x和y这条边的权值为0时,表示x和y是同类,当为1时,表示x吃y,当为2时,表示x被y吃. 一共有三种状态,如图,当A吃B,B吃 ...
- poj 1182 并查集高级应用
C - 是谁站在食物链的顶端 Crawling in process... Crawling failed Time Limit:1000MS Memory Limit:10000KB ...
- poj 1984 并查集
题目意思是一个图中,只有上下左右四个方向的边.给出这样的一些边, 求任意指定的2个节点之间的距离. 就是看不懂,怎么破 /* POJ 1984 并查集 */ #include <stdio.h& ...
- poj 1797(并查集)
http://poj.org/problem?id=1797 题意:就是从第一个城市运货到第n个城市,最多可以一次运多少货. 输入的意思分别为从哪个城市到哪个城市,以及这条路最多可以运多少货物. 思路 ...
- POJ 2492 并查集扩展(判断同性恋问题)
G - A Bug's Life Time Limit:10000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u S ...
- POJ 2492 并查集应用的扩展
A Bug's Life Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 28651 Accepted: 9331 Descri ...
- POJ 3228 [并查集]
题目链接:[http://poj.org/problem?id=3228] 题意:给出n个村庄,每个村庄有金矿和仓库,然后给出m条边连接着这个村子.问题是把所有的金矿都移动到仓库里所要经过的路径的最大 ...
- poj 1733 并查集+hashmap
题意:题目:有一个长度 已知的01串,给出多个条件,[l,r]这个区间中1的个数是奇数还是偶数,问前几个是正确的,没有矛盾 链接:点我 解题思路:hash离散化+并查集 首先我们不考虑离散化:s[x] ...
随机推荐
- 【咸鱼教程】protobuf在websocket通讯中的使用
教程目录一 protobuf简介二 使用protobuf三 Demo下载 参考: CSDN:Egret项目中使用protobuf(protobufjs) TS项目中使用Protobuf的解决方案(ba ...
- MONGOOSE – 让NODE.JS高效操作MONGODB(转载)
Mongoose库简而言之就是在node环境中操作MongoDB数据库的一种便捷的封装,一种对象模型工具,类似ORM,Mongoose将数据库中的数据转换为JavaScript对象以供你在应用中使用. ...
- undefined类型
undefined类型 只有一个特殊的值 undefined 在使用var声明变量但未对其加以初始化,这个变量的值就是undefined 值是undefined的情况: 1.显示声明并初始化变量值 ...
- Windows Server 2008 R2之三管理活动目录数据库
活动目录数据库包括数据库文件NTDS.dit和日志文件.考虑到最佳性能,在生产环境推荐将日志文件和数据库文件在单独的硬盘驱动器中或RAID中,同时要根据网络的规模,保证磁盘上有充足的剩余空间.由于活动 ...
- mvc 实现超时弹窗后跳转
为了实现保持登录状态,可以用cookie来解决这一问题 假设过期时间为30分钟,校验发生在服务器,借助过滤器,可以这样写 public class PowerFilter : AuthorizeAtt ...
- 1.8TF的分类
TF识别手写体识别分类 #-*- coding: utf-8 -*- # @Time : 2017/12/26 15:42 # @Author : Z # @Email : S # @File : 1 ...
- Oracle体系结构之参数文件管理
参数文件作用:主要用来记录数据库配置信息,数据库在启动时,需要读取参数文件中关于控制文件的信息,分配内存,打开进程,会话等.数据库启动时第一个读取参数文件. 参数文件分类: 1)pfile:文本文件, ...
- 洛谷P3826 蔬菜 [NOI2017] 贪心
正解:贪心 解题报告: umm,,,其实我还不会 废话我这么菜怎么可能懂QAQ 先占坑,想学习这题很久了呢QAQ
- SQL Server 学习博客分享列表(应用式学习 + 深入理解)
SQL Server 学习博客分享列表(应用式学习 + 深入理解) 转自:https://blog.csdn.net/tianjing0805/article/details/75047574 SQL ...
- laravel教程入门笔记
安装laravel框架 1.安装命令 composer create-project --prefer-dist laravel/laravel ytkah ytkah表示文件夹名,如果不写的话自动会 ...