带权并查集——食物链
Posted flydoggie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了带权并查集——食物链相关的知识,希望对你有一定的参考价值。
并查集是常见而且好用的一种数据结构。原因在于代码简练而且方便维护各种额外信息。带权并查集就是并查集的一种应用方式。原理其实就是普通并查集额外维护了一个结点的权数组。
例题:
本题的关系有三层 -> 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; }
以上是关于带权并查集——食物链的主要内容,如果未能解决你的问题,请参考以下文章