您的位置:首页 > 其它

并查集——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代码:

/*************************************************************************
> 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");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: