码迷,mamicode.com
首页 > 其他好文 > 详细

带权并查集——食物链

时间:2020-02-08 16:01:11      阅读:248      评论:0      收藏:0      [点我收藏+]

标签:方式   信息   并查集   class   不同的   ==   ace   names   nbsp   

并查集是常见而且好用的一种数据结构。原因在于代码简练而且方便维护各种额外信息。带权并查集就是并查集的一种应用方式。原理其实就是普通并查集额外维护了一个结点的权数组。

例题:

技术图片

 

 

 

 

本题的关系有三层 -> a -> b -> c -> ,但不同的是本题的关系是有向的,也就是说a和b如果是敌对关系,那么b和a就不是敌对关系。

关系传递的本质实际上是向量的运算。
还是设 d[x] 表示 x 与 fa[x] 的关系,0 代表是同类,1 代表是x吃fa[x], 根据关系图自然2就代表x被fa[x]吃。

#include<iostream>
using namespace std;

const int N = 500010;

int p[N];
int d[N];//带权并查集的权值0 1 2 三个值分别表示是同类,吃根节点,和被根节点吃;
int n,m,k,a,b;
int find(int x)
{
    if(p[x] == x) return x;
    int r = find(p[x]);
    d[x] += d[p[x]];
    return p[x] = r;
}


int main(){
    cin>>n>>m;
    for(int i = 0 ; i <= n ; i++){
        p[i] = i;
    }
    int res = 0;
    for(int i = 0 ; i < m ; i ++){
        cin>>k>>a>>b;

        if(a>n || b>n){
            res++;continue;    
        } 
        else if(k == 2 && a == b){
            res++;continue;
        }else{
            int x = find(a);int y = find(b);
            int t = 0;
            if(k==2) t = 1;
            if(x == y){
                if(  (((d[a] - d[b]) % 3) + 3) % 3 != t ){
                    res ++;

                }
            }else{
                p[x] = y;
                d[x] = d[b] - (d[a] - t);
            }

        }
    }
    cout<<res<<endl;


    return 0;
}

 

带权并查集——食物链

标签:方式   信息   并查集   class   不同的   ==   ace   names   nbsp   

原文地址:https://www.cnblogs.com/Flydoggie/p/12283513.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!