并查集——POJ 1182 食物链

来源:互联网 发布:淘宝二手铁艺设备 编辑:程序博客网 时间:2024/06/05 21:57
  • 题目链接: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.1415926535897932384626const 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");}
0 0
原创粉丝点击