POJ 1182 食物链

并查集。看了《挑战程序设计竞赛》才会的。POJ多组数据提交会WA。

主要思路是把一个点拆成三个点。i,i+n,i+2*n分别表示 i 是A类,B类,C类。

如果 i 和 j+n在同一集合内,表示 i 是A类的时候,j 一定是B类。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;

const int maxn=50000+10;
int n,k,ans;
int f[3*maxn];

int Find(int x)
{
    if(x!=f[x]) f[x]=Find(f[x]);
    return f[x];
}

void init()
{
    ans=0;
    for(int i=1;i<=3*n;i++) f[i]=i;
}

void u(int a,int b)
{
    int fa=Find(a),fb=Find(b);
    if(fa!=fb) f[fa]=fb;
}

bool p(int a,int b)
{
    int fa=Find(a),fb=Find(b);
    if(fa==fb) return 1;
    return 0;
}

void work()
{
    for(int i=1;i<=k;i++)
    {
        int d,x,y;
        scanf("%d%d%d",&d,&x,&y);
        if(x>n||y>n){ans++;continue;}
        if(d==1)
        {
            if(p(x,y+n)||p(x,y+2*n)) {ans++;continue;}
            u(x,y); u(x+n,y+n); u(x+2*n,y+2*n);
        }
        else if(d==2)
        {
            if(p(x,y)||p(y+2*n,x)) {ans++;continue;}
            u(x,y+n); u(x+n,y+2*n); u(x+2*n,y);
        }
    }
    printf("%d\n",ans);
}

int main()
{
    scanf("%d%d",&n,&k);
    init();
    work();
    return 0;
}

 

posted @ 2016-03-13 20:04  Fighting_Heart  阅读(213)  评论(0编辑  收藏  举报