并查集:POJ 1182 食物链 复习

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
using namespace std;

const int maxn = 100000*3 + 100;
int par[maxn];
int Rank[maxn];
int N, K;
int T[maxn], X[maxn], Y[maxn];

//初始化n个元素
void init(int n)
{
    for (int i = 0; i < n; i++)
    {
        par[i] = i;
        Rank[i] = 0;
     }
}

//查询树的根
int Find(int x)
{
    if (par[x] == x)
    {
        return x;
    }
    else
    {
        return par[x] = Find(par[x]);
    }
}

//合并x和y所述的集合
void unite(int x, int y)
{
    x = Find(x);
    y = Find(y);
    if (x == y) return;

    if (Rank[x] < Rank[y]) {
        par[x] = y;
    }
    else {
        par[y] = x;
        if (Rank[x] == Rank[y]) Rank[x]++;
    }
}

bool same(int x, int y)
{
    return Find(x) == Find(y);
}

void input()
{
    scanf("%d%d", &N, &K);
    for (int i = 0; i < K; i++)
    {
        scanf("%d%d%d", &T[i], &X[i], &Y[i]);
    }
}

void solve()
{
    input();
    //初始化并查集
    //元素x, x + N, x + 2*N 分别代表 x-A, y-B, x-C
    init(N * 3);

    int ans = 0;
    for (int i = 0; i < K; i++)
    {
        int t = T[i];
        int x = X[i] - 1, y = Y[i] - 1;   //把输入变成 0, ... , N-1 范围

        //不正确的编号
        if (x < 0 || x >= N || y < 0 || y >= N)
        {
            ans++;
            continue;
        } 

        if (t == 1)
        {
            //"x和y属于同一类"的信息
            if (same(x, y + N) || same(x, y + 2*N))
            {
                ans++;
            }
            else
            {
                //同属A,或B,或C类
                unite(x, y);
                unite(x + N, y + N);
                unite(x + 2*N, y + 2*N);
            }
        }
        else {
            //"x吃y"的信息错,同为一类,或者隔了1类
            if (same(x, y) || same(x, y + 2*N)) {
                ans++;
            }
            else {
                unite(x, y + N);          // A -> B
                unite(x + N, y + 2 * N);  // B -> C
                unite(x + 2 * N, y);      // C -> A
            }
        }
    }
    printf("%d\n", ans);
}

int main()
{
    solve();

    return 0;
}

原文地址:https://www.cnblogs.com/douzujun/p/8531093.html

时间: 2024-10-19 17:37:03

并查集:POJ 1182 食物链 复习的相关文章

[并查集] POJ 1182 食物链

食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 66294   Accepted: 19539 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同

又见关系并查集 以POJ 1182 食物链为例

简单的关系并查集一般很容易根据给出的关系搞出一个有向的环,那么两者之间的关系就变成了两者之间的距离. 对于此题: 若u,v不在一个集合内,则显然此条语句会合法(暂且忽略后两条,下同). 那么将fu 变为 fv的儿子时需加一条权值为 w 的边,w 满足(w + ru)%3 = (rv+ (D == 1? 0 : 1))%3(ru,rv分别为u,v与fv的关系,即距离). 之所以在D == 2时加 1,是因为u吃v表明着u到fv的距离比v到fv的距离大1. 同理,D == 1时,表明两者到fv的距离

poj 1182 食物链 (带关系的并查集)

  食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 44835 Accepted: 13069 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类.

POJ 1182 食物链【并查集】

题目链接:http://poj.org/problem?id=1182 此题利用并查集解决. 对于每只动物i创建3个元素i-A,i-B,i-C,并用这3*N个元素建立并查集. 1·i-x表示"i属于种类x" 2·并查集你的每一组表示组内所有元素代表的情况同时发生或不发生. 对于每一条信息,只需要按照下列操作即可: 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. 当然,在合并之前,

poj 1182:食物链(并查集,食物链问题)

食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 44168   Accepted: 12878 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同

带权并查集(含种类并查集)【经典模板】 例题:①POJ 1182 食物链(经典)②HDU - 1829 A bug&#39;s life(简单) ③hihoCoder 1515 : 分数调查

带权并查集: 增加一个 value 值,并且每次合并和查找的时候需要去维护这个 value 例题一 :POJ 1182 食物链(经典) 题目链接:https://vjudge.net/contest/339425#problem/E 带权并查集的解法 定义两个数组fa[ ]和rela[ ],fa用来判断集合关系,rela用来描述其与根节点的关系.因为关系满足传递性,所以可以推导出给出条件下的当前关系,在判断与之前已有关系是否矛盾. 本题的解法巧妙地利用了模运算,rela数组用0表示同类,1表示当

POJ 1182 食物链 Union Find题解

Union Find就是所谓的并查集. 本题做的很无语,最后发现居然是输入搞错,一直WA. 不能使用循环接受输入,否则是WA的,气死人,浪费那么多时间就为了这个. 难点: 1 构建关系树 2 构建公式 3 快速更新公式 要抽象思维出什么对应什么的关系和上面是逆关系,就是利用0,1,2构建出父子节点之间的关系值,我是这样去思考构建出准确无误的公式的. 这样的抽象度是挺高的,需要多多训练. 关系到数学和Union Find,难度还是挺高的,网上很多人解法了. 我这里就增加一个按权值更新的优化算法,和

Catenyms+欧拉回路/欧拉路+并查集+POJ

Catenyms Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9617   Accepted: 2524 Description A catenym is a pair of words separated by a period such that the last letter of the first word is the same as the last letter of the second. For e

POJ 1182 食物链 [并查集 带权并查集 开拓思路]

传送门 P - 食物链 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1182 Appoint description:  System Crawler  (2015-01-27) Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物