POJ 1182_食物链
2016-02-08 00:53
465 查看
题意:
三种动物A,B,C,A吃B,B吃C,C吃A,有人用两种说法对这N个动物所构成的食物链关系进行描述:
第一种说法是”1 X Y”,表示X和Y是同类。
第二种说法是”2 X Y”,表示X吃Y。
此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
1) 当前的话与前面的某些真的话冲突,就是假话;
2) 当前的话中X或Y比N大,就是假话;
3) 当前的话表示X吃X,就是假话。
求假话数
分析:
最初想到用三个并查集分别表示A,B,C,然后用数组表示之间的联系,可是操作起来很麻烦,过了样例也一直WA,后来看了《挑战程序设计竞赛》上的解法,用偏移量表示他们之间的关系,处理起来方便很多。即X为A,X+N为B,X+2*N为C
代码:
#include<iostream> #include<cstdio> using namespace std; const int maxn = 500055; int pa[maxn], _rank[maxn]; int _find(int x) { if(pa[x]==x) return x; else return pa[x]=_find(pa[x]); } void unite(int x, int y) { int rx = _find(x), ry = _find(y); if(rx==ry) return; if(_rank[rx]>_rank[ry]) pa[ry]=rx; else { pa[rx] = ry; if(_rank[rx]==_rank[ry]) _rank[ry]++; } return; } bool same(int x, int y) { return _find(x)==_find(y); } int main (void) { int n, k ;scanf("%d%d",&n,&k); for(int i = 1; i <= 3 * n; i++) pa[i] = i; int x, y, f, cnt = 0; int mod = 3 * n; for(int i = 0; i < k; i++){ scanf("%d%d%d",&f,&x,&y); if(x>n||y>n) {cnt++;continue;} if(f==1){ if(same(x,y+n)||same(x,y+2*n)) cnt++; else{ unite(x,y); unite(x+n,y+n); unite(x+2*n,y+2*n); } }else { if(same(x,y)||same(x, y + 2*n)) cnt++; else { unite(x, y+n); unite(x+n,y+2*n); unite(x+2*n, y); } } } printf("%d\n",cnt); }
相关文章推荐
- 面试笔试杂项积累-leetcode 156-160
- 01背包
- 面试笔试杂项积累-leetcode 151-155
- 2016,丙申(猴年)
- USACO--Barn Pepair
- android数据存储的四种方案(三)
- hdu 5621 KK's Point(数学,推理题)
- swift学习笔记之-继承
- could not open parameter file '/u01/app/oracle/product/11.1.0/db_1/dbs/initorc11g.ora
- [bzoj3295] [Cqoi2011]动态逆序对
- javascript计算器工作原理
- 面试笔试杂项积累-leetcode 146-150
- welcome to new life
- zoj3471 Most Powerful(状态压缩dp)
- POJ 1698 Alice's Chance(最大流)
- 春晚已经变成一种象征,已经变成了我们春节不可缺少的一部分。
- 祝福:新春新年大吉大利。问鼎天下,谁与争锋。非递归非交换非转数组非无序全排列组合算法,诚邀比、测、评。
- 2016新的一年
- 习题10-39 UVA 11186 Circum Triangle圆周上的三角形
- hdu4296 Buildings(贪心)