• 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;
    }
  • 相关阅读:
    Mac Finder 里新建文本
    SourceTree 无法查看组织仓库
    Android Gradle 指定 Module 打包
    Mac 下安装安卓 apk 文件
    Android 瘦身之道 ---- so文件
    Android Google AdMob 广告接入示例
    Java 垃圾回收(GC) 泛读
    [麻雀虽小]记 简易Markdown阅读器 开发全过程
    Git 版本回滚
    线程与进程的区别及其通信方式
  • 原文地址:https://www.cnblogs.com/rainydays/p/2090313.html
Copyright © 2020-2023  润新知