POJ 1182 食物链

来源:互联网 发布:税务申报软件 编辑:程序博客网 时间:2024/06/18 10:48

走你:http://poj.org/problem?id=1182

详情写在代码里了。有疑问请评论

#include <stdio.h>#include <algorithm>#include <string.h>#define MAXN 50010using namespace std;int r[MAXN],k,lie,f[MAXN],n;void init(){    int i;    //printf("init is right\n");    for(i=1; i<=n; i++)    {          /*r[]表示每个节点与其对应的根节点之间的关系,          0表示同类          1表示被父节点吃          2表示吃父节点*/        f[i] = i;   //父节点一开始全是自己        r[i] = 0;   //自己跟自己一定是同类吧    }}int find_father(int x){    if(x == f[x])        return x;    int t= f[x];                //记录x的父节点    f[x] = find_father(f[x]);   //找到X的祖宗节点    r[x] = (r[x]+r[t])%3;       //更新 x 与父节点之间的关系    /*        我们假设 x 与 y的关系r1,y 与 z关系r2                 x 与 z的关系为 (r1+r2)%3    */    return f[x];}void uninon(int x,int y,int d){    int fx= find_father(x);    int fy= find_father(y);    f[fy]= fx;    r[fy]= (3-r[y]+(d-1)+r[x])%3;    /*fx为x的根,fy为y的根      合并时要把fx设置为fy的父节点      fy  对 y的关系为  (3-r[y])%3      y   对 x的关系为  d-1      x   对 fx 的关系  r[x]      所以fy 对应fx的关系为(3-r[y]+r[x]+d-1)%3    */}int main(){    scanf("%d %d",&n,&k);//带权并查集  这题 的坑点在这,他不用多组测试数据    init();    lie=0;    int op,x,y;    for(int i=0; i<k; i++)    {        //printf("lie is %d\n",lie);        scanf("%d %d %d",&op,&x,&y);        if(x>n||y>n||(op==2 && x==y))            lie++;        else if(find_father(x) == find_father(y))        {            if(op==1 && r[x]!=r[y] )                lie++;            if(op==2 && (r[x]+1)%3 !=r[y])                lie++;        }        else uninon(x,y,op);    }    printf("%d\n",lie);    return 0;}
0 0
原创粉丝点击