题目链接http://poj.org/problem?id=1182

食物链
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 90077   Accepted: 27059

Description

动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。
现有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

第一行是两个整数N和K,以一个空格分隔。

以下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(并查集)的更多相关文章

  1. POJ-1182 食物链---并查集(附模板)

    题目链接: https://vjudge.net/problem/POJ-1182 题目大意: 中文题,不多说. 思路: 给每个动物创建3个元素,i-A, i-B, i-C i-x表示i属于种类x,并 ...

  2. POJ-1182 食物链 并查集(互相关联的并查集写法)

    题目链接:https://cn.vjudge.net/problem/POJ-1182 题意 中文题目,就不写了哈哈 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃 ...

  3. *HDU1829 并查集

    A Bug's Life Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  4. [poj1182]食物链(并查集+补集)

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 64841   Accepted: 19077 Description ...

  5. POJ-1182 分组并查集

    今天刚发现,之前做的并查集只是贴模板基本就能过,题意改变一点,自己还是不懂,其实我还没入门呢... 题意:食物链,A吃B,B吃C,C吃A,输入m组数据: 1 a b:a 和 b 是同一类 2 a b: ...

  6. poj1182食物链--并查集

    动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种.有人用两种说 ...

  7. poj1182(并查集)

    题目链接 分析:根据分析,关系的递推满足由[a,b]~[b,c]得:[a,c]=([a,b]+[b,c])%3;[a,d]=([a,b]+[b,c]+[c,d])%3.由rank数组表示关系 0 -  ...

  8. 食物链--poj1182(并查集含有关系)

    http://poj.org/problem?id=1182   题意应该就不用说了  再次回到食物链这道题,自己写了一遍,一直wa...原因竟然是不能用多实例,我也是醉了,但是我真的彻底的理解了,那 ...

  9. POJ1182 食物链 并查集

    #include<iostream>#include<stdio.h>#include<string.h>using namespace std;const int ...

  10. POJ1182 食物链---(经典种类并查集)

    题目链接:http://poj.org/problem?id=1182   食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submission ...

随机推荐

  1. SQL性能优化-order by语句的优化

    原文:http://bbs.landingbj.com/t-0-243203-1.html 在某些情况中,MySQL可以使用一个索引来满足ORDER BY子句,而不需要额外的排序.where条件和or ...

  2. [转帖]xargs命令详解,xargs与管道的区别

    xargs命令详解,xargs与管道的区别 https://www.cnblogs.com/wangqiguo/p/6464234.html 之前一直说要学习一下 xargs 到现在为止也没学习.. ...

  3. [转帖]分布式Unique ID的生成方法一览

    分布式Unique ID的生成方法一览 http://www.importnew.com/22211.html 分布式的Unique ID的用途如此广泛,从业务对象Id到日志的TraceId,本文总结 ...

  4. [转帖]再次提醒Google Chrome用户应尽快升级浏览器到72.0.3626.121

    再次提醒Google Chrome用户应尽快升级浏览器到72.0.3626.121 转帖地址: https://www.cnbeta.com/articles/tech/825591.htm 国内离线 ...

  5. 将表单数据转换为json代码分享

    <body> <form action="#" method="post" id="form1"> <inpu ...

  6. 不停机修改线上 MySQL 主键字段 以及其带来的问题和总结思考

    起因: 线上 user 数据库没有自增字段,数据量已经达到百万级.无论是给离线仓库还是数据分析同步数据,没有主键自增 id 都是杀手级的困难.所以在使用 create_time 痛苦了几次之后准备彻底 ...

  7. shell自定义输入输出 read+echo

    自定义格式输入.输出(244)  输出:echo -e 解释转义字符 -n  回车不换行 \n   新的一行,等同于回车 \t 制表符 \r 回车 \b 回退 baskspace 删除键 演示\n \ ...

  8. 关于浏览器兼容问题——还有移动端meta问题

    <!DOCTYPE html><!--[if lt IE 7]> <html dir="ltr" lang="en-US" cla ...

  9. 微信小程序支付功能

    API:wx.requestPayment() { } https://blog.csdn.net/qishubiao/article/details/80804052

  10. webpack模塊打包機

    https://blog.csdn.net/qq_38277366/article/details/82907894