poj_1182_食物链(并查集)

来源:互联网 发布:华硕truelife软件 编辑:程序博客网 时间:2024/05/07 05:50

题型:并查集


题意:中文题,不解释~


分析:

       典型的并查集应用。

       rank中存的秩为0、1、2,分别表示0吃1,1吃2,2吃0。

       将同种动物归于一个集合,查找判断是否为假话。


代码:

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#define MAXN 50050using namespace std;int father[MAXN];//father[x]表示x的父节点int rank[MAXN];//rank[x]表示x的秩void Make_Set(int x) { //初始化    father[x] = x;    rank[x] = 0;}int Find_Set(int x) {    int tmp = father[x];    if(x != father[x]) {        father[x] = Find_Set(father[x]);        rank[x] = (rank[x] + rank[tmp]) % 3;    }    return father[x];}void Union(int x,int y,int w) {    int a = Find_Set(x);    int b = Find_Set(y);    father[b] = a;    rank[b] = (rank[x] - rank[y] + w + 3) % 3;}int main() {    int n,m,num,x,y;    scanf("%d%d",&n,&m);    for(int i=1; i<=n; i++) {        Make_Set(i);    }    int ans = 0;    while(m--) {        scanf("%d%d%d",&num,&x,&y);        if(x>n || y>n) {            ans++;        } else {            if(num == 1) {                if(Find_Set(x) == Find_Set(y) && rank[x] != rank[y])                    ans++;                else Union(x,y,0);            } else {                if(Find_Set(x) == Find_Set(y) && (rank[x]+1)%3 != rank[y])                    ans++;                else Union(x,y,1);            }        }    }    printf("%d\n",ans);    return 0;}


原创粉丝点击