POJ 1182 食物链

来源:互联网 发布:天猫淘宝网 编辑:程序博客网 时间:2024/05/07 01:28

对于POJ 1182食物链的问题

首先应该考虑怎么分类?A B C 三个物种,1--N个动物。。。貌似不太好弄,仔细分析一哈,ABCD。。我们不妨用i-x来表示动物,并建立3*N的并查集

分为两类,一类是 x-Ay-Ax-By-Bx-Cy-C//xy是同一种类

另一类是x-Ay-Bx-By-Cx-Cy-A//x,y是吃的。


//代码实现

#include <iostream>

#include <cstdio>

#include <string>

#define MAX_N 200000

#define MAX_K 100005

using namespace std;

int n,k;

int T[MAX_K],X[MAX_K],Y[MAX_K];

//我们用编号代替每个元素,数组par表示的是父亲的编号,par[x]=x时,表示x是所在树的根

int par[MAX_N];

int rank[MAX_N];

 

//完成n个元素的初始化

void init(int n)

{

    for(int i=0;i<n;i++)

    {

        par[i]=i;

        rank[i]=0;

    }

}

 

//查询树的根

int find(int x)

{

    if(par[x]==x)

        return x;

    else

        return par[x]=find(par[x]);//路径压缩,对于每个节点,一旦向上走到了一次根节点,就把这个店到父亲的边改为直接连向边

 

}

 

//合并xy所属的集合

void unite(int x,int y)

{

    //找到xy的根,并判断根是否相同

    x=find(x);

    y=find(y);

    if(x==y)

        return ;

    //避免形成链

    if(rank[x]<rank[y])

    {

        //x设为y的子树

        par[x]=y;

    }

    else{

        par[y]=x;

        if(rank[x]==rank[y])

            rank[x]++;

    }

}

 

bool same(int x,int y)

{

    //只需要判断他们的根节点是否相同即可

    return (find(x)==find(y));

}

 

int main()

{

    scanf("%d %d",&n,&k);

    for(int i=0;i<k;i++)

    {

        scanf("%d %d %d",T+i,X+i,Y+i);

    }

    void solve();

    solve();

}

 

void solve()

{

    int ans=0;

    init(n*3);

    for(int i=0;i<k;i++)

    {

        int t=T[i];

        int x=X[i]-1;//将范围从0--N变为0--N-1

        int y=Y[i]-1;

 

        if(x<0||y<0||x>=n||y>=n)

        {

            ans++;

            continue;

        }

        if(t==1)

        {

            //证明xy是同一类

            if(same(x,y+n)||same(x,y+2*n))

                ans++;

            else{

//同一物种

                unite(x,y);

                unite(x+n,y+n);

                unite(x+2*n,y+2*n);

            }

        }

        else{

            //信息为xy;

            if(same(x,y)||same(x,y+2*n))

                ans++;

            else{

//吃的哪一类

                unite(x,y+n);

                unite(x+n,y+2*n);

                unite(x+2*n,y);

            }

        }

    }

    printf("%d\n",ans);

}

 

 

 


0 0