poj 食物链

来源:互联网 发布:海关出口数据 编辑:程序博客网 时间:2024/06/08 18:54

这里写图片描述

AC情况:这里写图片描述

思路:简化的并查集。
这个题目只需要输入一组,可以写的简单一点,但是第一次做这种题目,我想加深点印象所以把函数都完整的写了一下,以后回顾也方便。
因为一共有3种动物,且是循环的吃的关系,一般情况下不能确定谁是第一种谁是第二种第三种,所以把每个动物i都分成3个元素:i-A、i-B、i-C。如果输入说法1 x y,则说明x-A=y-A、x-B=y-B、x-C=y-C。如果输入说法2 x y,则说明x-A=y-B、x-B=y-C、x-C=y-A。定义i代表i-A,i+n代表i-B,i+2n代表i-C。

#include<iostream>using namespace std;const int MAX_N = 50001;int par[3*MAX_N],ran[3*MAX_N];int i;//初始化函数void init(int n) {    for (i = 0; i < n; i++) {        par[i] = i;        ran[i] = 0;    }}//找元素x的父节点int find(int x) {    int k, j, r;    r = x;    while (r != par[r])r = par[r];    k = x;    while (k != r) {        j = par[k];        par[k] = r;        k = j;    }    return r;}//合并元素x和yvoid unite(int x, int y) {    x = find(x);    y = find(y);    if (x == y)return;    if (ran[x] < ran[y]) {        par[x] = y;    }    else {        par[y] = x;        if (ran[x] = ran[y]) ran[x]++;    }}//检验x和y的父节点是否相同bool same(int x, int y) {    return find(x) == find(y);}int main() {    int n, k;    cin >> n >> k;    int t, x, y;    init(n * 3);    int ans = 0;    for (i = 0; i < k; i++) {        cin >> t >> x >> y;        x--;           //把输入元素的范围调整为0~n-1,因为要根据par[x]寻找父节点,par是从0存的        y--;        if (x >=n || y >= n) {            ans++;            continue;        }        if (t == 1) {            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 {            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 );            }        }    }    cout << ans<<endl;    return 0;}
原创粉丝点击