并查集——POJ 1182 食物链
2017-03-25 18:52
423 查看
题目链接:http://poj.org/problem?id=1182
题意:给出N只动物,它们属于A,B,C三种类型,其中A吃B,B吃C,C吃A,接下来给出K句话描述它们的关系:一种是 1,x,y 表示x,y是属于一类,另一种 2,x,y 表示x吃y。某一句话为假,当且仅当,x或者y超出范围,或者 x等于y,或者这句话和前面的真话矛盾,求假话的数量
分析:这里一共要维护两种关系:捕食关系和归属关系。刚开始,我们可能会想到设定给每一种动物判定一种类型,通过判断这些动物属于的类型是否构成矛盾来计算假话的数量。不过很快,我们就发现我们并不能确定每一种动物的类型!为之奈何?我有很无奈啊,那既然不知道它属于哪一种,那我们就把同时计算它属于每一种的情况,每次更新这三个类型,如果其中一种情况出了问题,那么肯定就是假的了(这个仔细想想,可以发现时必然成立的)
具体做法:如果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。这样就可以安心玩并查集了
AC代码:
题意:给出N只动物,它们属于A,B,C三种类型,其中A吃B,B吃C,C吃A,接下来给出K句话描述它们的关系:一种是 1,x,y 表示x,y是属于一类,另一种 2,x,y 表示x吃y。某一句话为假,当且仅当,x或者y超出范围,或者 x等于y,或者这句话和前面的真话矛盾,求假话的数量
分析:这里一共要维护两种关系:捕食关系和归属关系。刚开始,我们可能会想到设定给每一种动物判定一种类型,通过判断这些动物属于的类型是否构成矛盾来计算假话的数量。不过很快,我们就发现我们并不能确定每一种动物的类型!为之奈何?我有很无奈啊,那既然不知道它属于哪一种,那我们就把同时计算它属于每一种的情况,每次更新这三个类型,如果其中一种情况出了问题,那么肯定就是假的了(这个仔细想想,可以发现时必然成立的)
具体做法:如果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。这样就可以安心玩并查集了
AC代码:
/************************************************************************* > File Name: test.cpp > Author: Akira > Mail: qaq.febr2.qaq@gmail.com ************************************************************************/ #include <iostream> #include <sstream> #include <cstdio> #include <cstring> #include <string> #include <cstdlib> #include <algorithm> #include <bitset> #include <queue> #include <stack> #include <map> #include <cmath> #include <vector> #include <set> #include <list> #include <ctime> #include <climits> typedef long long LL; typedef unsigned long long ULL; typedef long double LD; #define MST(a,b) memset(a,b,sizeof(a)) #define CLR(a) MST(a,0) #define Sqr(a) ((a)*(a)) using namespace std; #define MaxN 200010 #define MaxM MaxN*10 #define INF 0x3f3f3f3f #define PI 3.1415926535897932384626 const int mod = 1E9+7; const double eps = 1e-6; #define bug cout<<88888888<<endl; #define debug(x) cout << #x" = " << x; int N,K; int fa[MaxN]; int getfather(int x) { int fx=fa[x]; if(fx!=x) { fx=getfather(fa[x]); } return fa[x]=fx; } void U(int x,int y){ int fx=getfather(x),fy=getfather(y); if(fx!=fy) fa[fy]=fx; } int main() { //std::ios::sync_with_stdio(false); scanf("%d%d", &N, &K); for(int i=1;i<=3*N;i++){ fa[i]=i; } int ans = 0; int type,x,y; while(K--) { scanf("%d%d%d", &type, &x, &y); if(x<0||x>N||y<0||y>N||(type==2&&x==y)) { ans++; continue; } if(type==1) { // A B C // x x+N x+2N // y y+N y+2N int fx = getfather(x); int fy1 = getfather(y+N); int fy2 = getfather(y+2*N); if( fx == fy1 || fx == fy2) ans++; else{ U(x,y); U(x+N, y+N); U(x+2*N, y+2*N); } } else { int fx = getfather(x); int fy1 = getfather(y); int fy2 = getfather(y+2*N); if( fx == fy1 || fx == fy2) ans++; else{ U(x,y+N); U(x+N, y+2*N); U(x+2*N, y); } } } printf("%d\n", ans); //system("pause"); }
相关文章推荐
- poj 1182 食物链 【带权并查集】
- poj 1182 食物链(并查集)
- poj 1182_食物链_并查集
- POJ 1182 食物链【并查集】
- [ACM] poj 1182 食物链(并查集)
- POJ - 1182 食物链(带权并查集)
- kuangbin专题五 并查集 POJ 1182食物链(带权并查集)重要
- 【POJ】1182 - 食物链(带权并查集,单数据)
- poj 1182 食物链(带权并查集)
- POJ 1182-食物链 [并查集] 《挑战程序设计竞赛》2.4
- poj1182 食物链[并查集]
- 【带权并查集】POJ1182 [NOI2001]食物链
- poj 1182 食物链(数据结构:并查集+路径压缩)
- 又见关系并查集 以POJ 1182 食物链为例
- POJ1182-食物链(经典并查集)
- 并查集-poj-1182-食物链-带权值的并查集
- POJ1182 食物链 (并查集)*新方法
- POJ 1182 食物链 带权并查集入门
- poj 1182 食物链 (种类并查集经典题)
- POJ1182---食物链(带权并查集~技巧性超强的解法)