【E - 食物链】

思路:

  • 基础种类并查集,注意取余+3
  • 读到文件尾会 WA,真是

总结:

  • 逻辑判断类题,当同属于同一集合(头元素相同)时进行判断;不属于同一集合时,合并。

代码:

  • 282ms 1116kB
//282ms		1116kB


#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 50005;

int N,K;
int ans;
int par[maxn];
int val[maxn];

void INIT(){
	ans = 0;
	memset(par , -1 , sizeof(par)) ;
	memset(val , 0  , sizeof(val)) ;
	return ;
}

int FIND(int i){
	if(par[i] == -1)
		return i;
	int temp = par[i];
	par[i] = FIND(par[i]);
	val[i] = (val[temp] + val[i])%3;
	return par[i];
}

void UNION(int w,int l,int r,int parl,int parr){
	par[parr] = parl;
	val[parr] = (val[l] + w - val[r] + 3) % 3;
	return ;
}

int main(){
	cin>>N>>K;
	INIT();
	while(K--){
		int type ;
		int l , r;
		scanf("%d%d%d" , &type , &l , &r);
		if(l>N || r>N || l<1 || r<1 || (type == 2 && l == r)){
			ans++ ;
			continue;
		}
		int parl = FIND(l);
		int parr = FIND(r);
		if(type == 1){
			if(parr == parl)
				if(val[l] != val[r])
					ans++;
				else	 ;
			else
				UNION(0 , l , r , parl , parr);
		}
		else{
			if(parr == parl)
				if((val[l] + 1)%3 != val[r])
					ans++;
				else	 ;
			else
				UNION(1 , l , r , parl , parr);
		}
	}
	cout<<ans<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/flash403/article/details/94335707