食物链(带权并查集)

食物链

在这里插入图片描述

在这里插入图片描述
输入样例:

100 7
1 101 1 
2 1 2
2 2 3 
2 3 3 
1 1 3 
2 3 1 
1 5 5

输出样例:

3

模板:

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

const int N = 50005;
int n, m;
int p[N], d[N];
//0 表示与根节点同类, 1表示被根节点吃, 2表示吃根节点 
int find(int x)
{
	if(p[x] != x)
	{
		int root = find(p[x]);
		d[x] += d[p[x]];
		p[x] = root;
	}
	return p[x]; 
}

int main()
{
	cin >> n >> m;
	int cnt = 0;
	for(int i = 1; i <= n; i ++ ) p[i] = i;
	
	for(int i = 1; i <= m; i ++ )
	{
		int op, a, b;
		scanf("%d%d%d", &op, &a, &b);
		if(a > n || b > n || (op == 2 && a == b))
		{
			cnt ++;
			continue;
		}
		int pa = find(a), pb = find(b);
		
		if(op == 2)
		{
			if(pa == pb && (d[b] - d[a] + 300) % 3 != 1) cnt ++;
			else
			{
				d[pb] = (d[a] - d[b] + 304) % 3;
				p[pb] = pa; 
			}
		}
		else
		{
			if(pa == pb && (d[b] - d[a] + 300) % 3) cnt ++;
			else
			{
				d[pb] = (d[a] - d[b] + 300) % 3;
				p[pb] = pa;
			}
		}
	}
	cout << cnt << endl;
	return 0;
} 

 

posted @ 2022-03-22 14:59  panse·  阅读(143)  评论(0)    收藏  举报