zoukankan      html  css  js  c++  java
  • poj1182

    题意:ABC三个物种构成循环捕食的食物网。给出一些捕食与同类 关系,询问一些关系是否正确。

    分析:并查集,但要随时记录并更新每个元素与其父亲之间的关系。用rank数组记录与父亲的关系。若为rank[x]==1则x吃其父亲,0表示同类,-1表示被吃。我们认为并查集中每个集合中的所有的动物都站在一条数轴上,每个点可以站多个动物,他们占据了一些连续的点。若b在a的右邻位则b吃a,若a,b相距是3的整数倍,则ab同类。这样以来rank数组的意义就变成了该动物与其父亲的在数轴上的差距(有正负)。当我们确定了a,b到祖先的距离时,只需要用rank[a]-rank[b]就可以获得a到b的距离。

    View Code
    #include <iostream>
    #include
    <cstdio>
    #include
    <cstdlib>
    #include
    <cstring>
    usingnamespace std;

    #define maxn 50005

    int n, m;
    int father[maxn], rank[maxn];

    int getanc(int a)
    {
    if (father[a] == a)
    return a;
    int ret = getanc(father[a]);
    rank[a]
    = (rank[father[a]] + rank[a]) %3;
    father[a]
    = ret;
    return ret;
    }

    void merge(int a, int b)
    {
    father[getanc(a)]
    = getanc(b);
    }

    bool ok(int order, int a, int b)
    {
    if (a > n || b > n || (order ==2&& a == b))
    returnfalse;
    int fa = getanc(a);
    int fb = getanc(b);
    if (fa != fb)
    {
    merge(fa, fb);
    rank[fa]
    = (rank[b] - rank[a] + order -1+3) %3;
    returntrue;
    }
    return (rank[a] - rank[b] +3) %3== order -1;
    }

    int main()
    {
    //freopen("t.txt", "r", stdin);
    scanf("%d%d", &n, &m);
    for (int i =0; i < n; i++)
    father[i]
    = i;
    memset(rank,
    0, sizeof(rank));
    int ans =0;
    for (int i =0; i < m; i++)
    {
    int order, a, b;
    scanf(
    "%d%d%d", &order, &a, &b);
    if (!ok(order, a, b))
    ans
    ++;
    }
    printf(
    "%d\n", ans);
    return0;
    }
  • 相关阅读:
    人月神教α阶段冲刺报告(6/12)
    人月神教α阶段冲刺报告(5/12)
    人月神教-α阶段冲刺报告(4/12)
    人月神教-α阶段冲刺报告(3/12)
    结对作业2
    结对作业1
    软工实践作业1
    Matrix Power Series(POJ 3233)
    Blocks(POJ 3734)
    Traveling by Stagecoach(POJ 2686)
  • 原文地址:https://www.cnblogs.com/rainydays/p/2090313.html
Copyright © 2011-2022 走看看