并查集:POJ 1182 食物链 复习

Posted 豆子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并查集: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;
}

 

以上是关于并查集:POJ 1182 食物链 复习的主要内容,如果未能解决你的问题,请参考以下文章

poj1182 食物链(并查集 好题)

POJ1182 食物链 —— 带权并查集

POJ1182并查集

带权并查集(含种类并查集)经典模板 例题:①POJ 1182 食物链(经典)②HDU - 1829 A bug's life(简单) ③hihoCoder 1515 : 分数调查(示例代码(代

POJ 1182 食物链 种类并查集

POJ1182 食物链---(经典种类并查集)