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

POJ 1182

时间:2020-07-15 23:39:09      阅读:63      评论:0      收藏:0      [点我收藏+]

标签:end   ret   题目   ini   find   string   ring   ace   cout   

重新做了一下这道并查集的题目,关键要点是抓住这种循环的关系和模运算的通性,进而利用加权并查集

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

const int maxn = 5e4+3;
const int maxk = 1e5+3;

// tp 0: same 1: eat fa 2: eaten by fa
int tp[maxn], fa[maxn];

int Find(int x)
{
	if (x== fa[x]){
		return x;
	}

	int tf= fa[x];
	fa[x]= Find(tf);

	tp[x]= (tp[tf]+tp[x])%3;

	return fa[x];
}
void MakeSet(int n)
{
	for (int i= 1; i<= n; ++i){
		fa[i]= i;
	}
}
void Init(int n)
{
	memset(tp, 0, sizeof(tp));
	MakeSet(n);
}
int Union(int op, int a, int b)
{
	int pa= Find(a);
	int pb= Find(b);

	if (pa== pb){
		if (tp[a]== tp[b] && 1== op){
			return 1;
		}
		if ((1== ((3+tp[a]-tp[b])%3)) && 2== op){
			return 1;
		}

		return 0;
	}

	fa[pa]= pb;
	tp[pa]= (op-1+tp[b]+3-tp[a])%3;

	return 1;
}

int main()
{
	int n, k, ans= 0, op, x, y;
	scanf("%d %d", &n, &k);
	Init(n);

	for (int i= 0; i< k; ++i){
		scanf("%d %d %d", &op, &x, &y);
		if (x> n || y> n){
			++ans;
			continue;
		}
		if (!Union(op, x, y)){
			++ans;
		}
	}

	cout<<ans<<endl;

	return 0;
}

POJ 1182

标签:end   ret   题目   ini   find   string   ring   ace   cout   

原文地址:https://www.cnblogs.com/Idi0t-N3/p/13307707.html

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