poj 1182

题意:都是中文的,大家都懂的,不解释了。

最近状态不怎么好,在北京赛区的网络赛的前一晚写这题,一直wa,wa到两点多,还是wa,重写了3遍还是wa,第二天起来继续wa,结果下午比赛一直困困的,结果挺悲剧的,又是死在一题上,队友把int型定义成char的型,结果一直在那里一起找错误。这题wa的原因:不能用while(scanf("%d%d",&n,&m)!=EOF);要单组输入;囧啊。。。

讲讲这题,并查集的拓展。

主要是要加个关系进去,k=0:表示同类;k=1,表示吃;k=2,表示被吃;

因为三种动物循环吃,所以关系有这样

x->k1->y;   y->k2->z;

x->(k1+k2)%3->z,

y->(3-k1)->x;  

z->(3-k2)->y;

这些成立,那么可以推导任意两个之间的关系了。合并时用

Run ID User Problem Result Memory Time Language Code Length Submit Time
9340873 201030720425 1182 Accepted 556K 250MS C++ 911B 2011-09-21 10:52:18
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
int n,m;
struct node
{
	int k,f;
}nd[50005];
int find(int x)
{
	if(x==nd[x].f)return x;
	int tem=nd[x].f;
	nd[x].f=find(tem);
	nd[x].k=(nd[x].k+nd[tem].k)%3;
	return nd[x].f;
}
void unionit(int D,int x,int y,int fx,int fy)
{
	nd[fy].f=fx;
	nd[fy].k=(nd[x].k+D+2-nd[y].k)%3;
}
int deal(int D,int x,int y)
{
	if(x>n||y>n)return 1;
	int fx=find(x),fy=find(y);
	if(fx!=fy)unionit(D,x,y,fx,fy);
	else
	{
		if(D==1&&nd[x].k!=nd[y].k)return 1;
		if(D==2&&(3-nd[x].k+nd[y].k)%3!=1)return 1;
	}
	return 0;
}
void init()
{
	for(int i=0;i<=n;i++)nd[i].f=i,nd[i].k=0;
}
int main()
{
	int D,x,y,ans=0;
	scanf("%d%d",&n,&m);
	init();
	for(int i=0;i<m;i++)
	{
		scanf("%d%d%d",&D,&x,&y);
		ans+=deal(D,x,y);
	}
	printf("%d\n",ans);
	return 0;	
}


你可能感兴趣的:(poj 1182)