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 ...
随机推荐
- JS刷新当前页面的几种方法总结
reload 方法,该方法强迫浏览器刷新当前页面. 语法:location.reload([bForceGet]) 参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当前页 ...
- If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
学习Spring Boot 过程中遇到了下列这个问题 Description: Failed to configure a DataSource: 'url' attribute is not spe ...
- linux之ssh互信
1.如果你是之作root用户互信的话,直接一路执行如下命令就行. 1.切换你需要互信的账户 su hadoop1 2.执行命令,一路回车即可(在当前用的宿主用户目录下的.ssh目录下生成公钥和秘钥id ...
- 阿里云ECS服务器,CentOS 7.4配置jdk+tomcat+mysql
参考博客: https://mp.weixin.qq.com/s?__biz=MzIxMzk3Mjg5MQ==&mid=2247484020&idx=1&sn=6e0aa07f ...
- springboot+jpa+mysql+swagger整合
Springboot+jpa+MySQL+swagger整合 创建一个springboot web项目 <dependencies> <dependency> < ...
- 避免MQ消息重发的简单实现思路
一.MQ消息发送 一.MQ消息发送 1.发送端MQ-client(消息生产者:Producer)将消息发送给MQ-server: 2.MQ-server将消息落地: 3.MQ-server回ACK给M ...
- Web API 2 自定义默认Identity Table Name
One of the first issues you will likely encounter when getting started with ASP.NET Identity centers ...
- Django restframe 视图函数以及ModelSerializer的使用
建立model数据库 from django.db import models __all__ = ['Book', 'Publisher', 'Author'] # Create your mode ...
- 关于i++和i++的左值、右值问题
1.什么是左值和右值? 左值就是出现在表达式左边的值(等号左边),可以被改变,他是存储数据值的那块内存的地址,也称为变量的地址: 右值是指存储在某内存地址中的数据,也称为变量的数据. 左值可以作为右值 ...
- SQL Server查询优化器的工作原理
SQL Server的查询优化器是一个基于成本的优化器.它为一个给定的查询分析出很多的候选的查询计划,并且估算每个候选计划的成本,从而选择一个成本最低的计划进行执行.实际上,因为查询优化器不可能对每一 ...