互いに素セットに右で食物連鎖を解くPOJ 1182レポート

食物連鎖を解くPOJ 1182レポート

問題解決のアイデア:この質問は、パス圧縮およびマージの関係でコレクションを更新する方法では困難である点を示し、他の人のブログ、非常に巧妙なアプローチを読み、同じルートノード0と、1とルートノードポイントが食べていることを示します、 2点が3つだけのケースがあったので、方法の3%との関係を更新することが可能である、食べるためにルートノードで表され、それは非常に便利です。コードを直接見ては、注記を追加しました。最後にTucao直接WAを使用している間、ちょうど逆の問題であるワシントン州の中、nおよびmが、入力しないいくつかの未知の問題について。
ここに画像を挿入説明

#include <stdio.h>
#include<iostream>
#include <algorithm>
#include<string.h>
#include<cmath>
#pragma warning(disable:4996)
#define mod 1000000007
#define ll unsigned long long
const int N = 50005;
using namespace std;
int sum[N];
int father[N];
int find(int x)
{
	if (x != father[x])
	{
		int tem = father[x];//记录上一级
		father[x] = find(father[x]);//更新最高上级,即路径压缩
		sum[x] = (sum[x] + sum[tem]) % 3;//通过该点和上一级的联系,来更新该点和根节点的联系
	}
	return father[x];
}
int main()
{
	int  n, m;
	scanf("%d%d", &n, &m);

	int ans = 0;
	memset(sum, 0, sizeof(sum));
	for (int i = 0; i <= n; i++)
	{
		father[i] = i;
	}
	while (m--)
	{
		int  d, x, y;
		scanf("%d%d%d", &d, &x, &y);
		if (x > n || y > n)
		{
			ans++;
			continue;
		}
		else if (2 == d && x == y)
		{
			ans++;
			continue;
		}
		else
		{
			int fx = find(x);
			int fy = find(y);
			if (fx != fy)//说明两个点没有在一颗树上
			{
				father[fy] = fx;
				sum[fy] = (d - 1 + sum[x] - sum[y] + 3) % 3;//现在fx是根节点,通过x和fx的关系更新fy和fx的关系,+3保证数值非负
			}
			else
			{
				if (d == 1 && sum[x] != sum[y])
					ans++;
				if (d == 2 && (sum[x] + 1) % 3 != sum[y])
					ans++;
			}
		}
	}
	printf("%d\n", ans);

}


公開された64元の記事 ウォンの賞賛0 ビュー1438

おすすめ

転載: blog.csdn.net/weixin_45566331/article/details/105094754