poj1182、hdu1829(并查集)
题目链接:http://poj.org/problem?id=1182
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 90077 | Accepted: 27059 |
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
解题思路:题解来源于挑战程序设计,对于每只动物i创建3个元素i-A,i-B,i-C,并利用这3*N个元素建立并查集。这个并查集维护如下关系: i-x表示“i属于种类x“。
并查集里的每一个组表示组内所有元素代表的情况都同时发生或不发生。 例如,如果i-A和j-B在同一个组里,就表示如果i属于种类A那么j一定属于种类B,如果j属于种类B那么i一定属于种类A。因此对于每一条信息,只需按照如下进行操作就可以了。
第一种:x和y属于同一类,合并x-A和y-A,x-B和y-B,x-C和y-C。
第二种:x吃y 合并x-A和y-B,x-B和y-C,x-C和y-A。 不过在合并前,需要先判断合并是否会产生矛盾。例如在第一种情况下,需要先检查比如x-A和y-B或者y-C是否在同一组等信息。
附上代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=;
int n,k;
int par[maxn]; //父亲
int rank[maxn]; //树的高度 //初始化n个元素
void init(int n)
{
for(int i=;i<n;i++)
{
par[i]=i;
rank[i]=;
}
}
//查询树的根
int find(int x)
{
if(par[x]==x)
return x;
else
return par[x]=find(par[x]);
}
//合并x和y所属的集合
void unite(int x,int y)
{
if(find(x)==find(y))
return;
else
{
if(rank[find(x)]<rank[find(y)])
par[find(x)]=find(y);
else
{
par[find(y)]=find(x);
if(rank[find(x)]==rank[find(y)])
rank[find(x)]++;
}
}
}
//判断x和y是否在同一个集合
bool same(int x,int y)
{
return find(x)==find(y);
} int main()
{
scanf("%d%d",&n,&k);
//初始化并查集
//元素x,x+n,x+2*n分别为x-A,x-B,x-C
init(n*); int ans=;
for(int i=;i<k;i++)
{
int t,x,y;
scanf("%d%d%d",&t,&x,&y);
x-=,y-=; //把输入变成0~n-1的范围
//编号非法直接跳过
if(x<||x>=n||y<||y>=n)
{
ans++;
continue;
}
if(t==) //x和y属于同一类
{
if(same(x,y+n)||same(x,y+*n))
ans++;
else
{
unite(x,y);
unite(x+n,y+n);
unite(x+n*,y+n*);
}
}
else //x吃y
{
if(same(x,y)||same(x,y+*n))
ans++;
else
{
unite(x,y+n);
unite(x+n,y+*n);
unite(x+*n,y);
}
}
}
printf("%d\n",ans);
return ;
}
相似题:hdu1829 A Bug's Life
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1829
题目大意::给你n个虫,输入m行a,b,表示a和b是异性,要你判断是否有同性恋
解题思路:类型基本一致,比那个更简单,情况就两种,同性和异性,建立两个集合就行,如果输入的a、b同时存在一个集合当中,说明他们就是同性恋了。
附上代码:
#include<stdio.h>
int par[],rank[]; void init(int x)
{
for(int i=;i<=x;i++)
{
par[i]=i;
rank[i]=;
}
} int find(int x)
{
if(x==par[x])
return x;
else
return par[x]=find(par[x]);
} void unite(int x,int y)
{
int rootx=find(x);
int rooty=find(y);
if(x==y)
return;
if(rank[rootx]<rank[rooty])
par[rootx]=rooty;
else
{
par[rooty]=rootx;
if(rank[rootx]==rank[rooty])
rank[rootx]++;
}
} bool same(int x,int y)
{
return find(x)==find(y);
} int main()
{
int t;
scanf("%d",&t);
int kase=;
while(t--)
{
int n,m;
int flag=;
scanf("%d%d",&n,&m);
init(n*);
while(m--)
{
int a,b;
scanf("%d%d",&a,&b);
unite(a,b+n);
unite(a+n,b);
if(same(a,b)||same(a+n,b+n))
flag=;
}
printf("Scenario #%d:\n",kase++);
if(flag)
printf("Suspicious bugs found!\n");
else
printf("No suspicious bugs found!\n");
printf("\n");
}
return ;
}
poj1182、hdu1829(并查集)的更多相关文章
- POJ-1182 食物链---并查集(附模板)
题目链接: https://vjudge.net/problem/POJ-1182 题目大意: 中文题,不多说. 思路: 给每个动物创建3个元素,i-A, i-B, i-C i-x表示i属于种类x,并 ...
- POJ-1182 食物链 并查集(互相关联的并查集写法)
题目链接:https://cn.vjudge.net/problem/POJ-1182 题意 中文题目,就不写了哈哈 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃 ...
- *HDU1829 并查集
A Bug's Life Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- [poj1182]食物链(并查集+补集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 64841 Accepted: 19077 Description ...
- POJ-1182 分组并查集
今天刚发现,之前做的并查集只是贴模板基本就能过,题意改变一点,自己还是不懂,其实我还没入门呢... 题意:食物链,A吃B,B吃C,C吃A,输入m组数据: 1 a b:a 和 b 是同一类 2 a b: ...
- poj1182食物链--并查集
动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种.有人用两种说 ...
- poj1182(并查集)
题目链接 分析:根据分析,关系的递推满足由[a,b]~[b,c]得:[a,c]=([a,b]+[b,c])%3;[a,d]=([a,b]+[b,c]+[c,d])%3.由rank数组表示关系 0 - ...
- 食物链--poj1182(并查集含有关系)
http://poj.org/problem?id=1182 题意应该就不用说了 再次回到食物链这道题,自己写了一遍,一直wa...原因竟然是不能用多实例,我也是醉了,但是我真的彻底的理解了,那 ...
- POJ1182 食物链 并查集
#include<iostream>#include<stdio.h>#include<string.h>using namespace std;const int ...
- POJ1182 食物链---(经典种类并查集)
题目链接:http://poj.org/problem?id=1182 食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submission ...
随机推荐
- css 图片文字垂直居中
先来看张图片 相信很多css新手遇到过这种问题,就是当图片和文本显示在一行的时候,效果很奇葩,文字和图片没法对齐, 这时我们需要做的是: 1,先给块级元素设置 display: inline-bloc ...
- PMP三点
三点估算:悲观36天,可能21天,乐观6天.在16至26天内完成的概率是多少?这个算法是PERT估算最终估算结果=(悲观工期+乐观工期+4×最可能工期)/6=(36+6++4*21)/6=21标准差= ...
- SQL年月日格式化
Select CONVERT(varchar(100), GETDATE(), 23): 2006-05-16
- windows 10 multi virtual desktop keyboard shortcut
windows 10 multi virtual desktop keyboard shortcut windows 10 multi desktop keyboard shortcut https: ...
- MySQL系列:索引基本操作(4)
1. 索引简介 索引是一种特殊的数据库结构,可以用来快速查询数据中的特定记录. MySQL中索引包括:普通索引.唯一性索引.全文索引.单列索引.多列索引和空间索引等. 1.1 索引定义 索引由数据库表 ...
- javascript中 json数据的解析与序列化
首先明确一下概念: json格式数据本质上就是字符串: js对象:JavaScript 中的几乎所有事务都是对象:字符串.数字.数组.日期.函数,等等. json数据的解析: 就是把后端传来的json ...
- 导出数据到EXL表格中
项目使用的是SSI框架,通过struts访问到action xml文件: <action name="fabAttributedaochu" class="com. ...
- Mvc校验用户没有登录就跳转的实现
看字面意思很简单,就是判断用户是否登录了,如果没有登录就跳转到登陆页面. 没错,主要代码如下(这里就不写判断登录了,直接跳转) 首先在控制器中新建一个BaseController public cla ...
- ES6函数增强
函数参数可以拥有默认值.调用函数时,如果没有进行相应的实参传递,参数就会使用默认值.怎么给参数提供默认值呢?很简单,声明函数时候,给形参赋一个值就可以了,这个值就是参数的默认值. // num2拥有默 ...
- 【bzoj1150】[CTSC2007]数据备份Backup 模拟费用流+链表+堆
题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游戏 ...