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 ...
随机推荐
- python之路--MySQL多表查询
一 介绍 我们在写项目的时候一般都会建一个数据库,数据库里面会存很多的表,不可能把所有的数据都放在一张表里,因为分表来存数据节省空间,数据的组织结构更清晰,解耦和程度更高,但是这些表本质上还不是一个整 ...
- Golang的面向对象实践method
最近在系统的学习go的语法,一切都弄好了之后准备弄个im项目出来玩.在这个过程中会把看到有趣的写法和语法啥的拿出来分析一下. 我一直以为go语言对面向对象没有支持,但是后面看到了类似类的概念,meth ...
- 织梦后台如何生成站点地图sitemap.xml
第一步在网站根目录建立sitemap.php文件 内容如下: 写一个计划任务文件命名为generate_sitemap.php,放在/plus/task目录里,文件内容如下: <?php//定时 ...
- MyBatis基础:MyBatis数据基本操作(2)
1. MyBatis映射器 2. MyBatis数据基本操作 示例项目结构: <project xmlns="http://maven.apache.org/POM/4.0.0&quo ...
- vue組件
組件有局部組件和全局組件,全局組件,其它的元素能夠調用. Prop父組件子組件看不大明白.
- Java使用RabbitMQ之整合Spring(消费者)
依赖包: <!--RabbitMQ集成spring--> <!-- https://mvnrepository.com/artifact/org.springframework.am ...
- JQ和JS获取元素
<ul> <li>John</li> <li>Karl</li> <li>Brandon</li> </u ...
- 了解C#中的HashSet与示例
在C#中引入HashSet 在.NET框架中,有几个类可用于执行这些操作.一些课程如下: 列表 字典 哈希集 队列 集合 在C#编程中,像ArrayList,List这样的集合,只需添加其中的值,而不 ...
- .net core Include问题
本文章为原创文章,转载请注明出处 当时不知道为什么这样写,可能是突然间脑子停止了转动,既然犯过这样的错误,就记录下来吧 错误示例 ).Include(a=>a.User).Select(a =& ...
- java Builder模式创建不可变类
package com.geostar.gfstack.operationcenter.logger.manager.common; /** * Created by Nihaorz on 2017/ ...