void-man

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

给出一个木棒两端的颜色,问相同颜色的木棒可以连到一起,是否可以把所有木棒相连

此题遇到很多问题,首先判断欧拉路好办,求出入度出度就ok,关键是怎么存储?放到数组然后每次查询一次??tle

用map?很难给字符串编号。。。那就用字典树吧。。。。但是还要注意,必须要判断连通性,这里又是个问题

这么大的数据量,就用并查集来判断连通吧,好了,到此问题解决了,看代码吧。。。

#include<iostream>
#include<cstring>
using namespace std;
char clr1[11],clr2[11];   
int p[500010];   
int r[500010];   
int rec[500010];   
int num=1;  
struct node
{
	int id,i;
	node*next[27];
	node()
	{
		for(i=0;i<27;i++)
			next[i]=NULL;
		id=0;
	}
};
node*root=new node;
void insert(char*temp)
{
	int len=strlen(temp);
	int i;
	node*p=root;
	for(i=0;i<len;i++)
	{
		if(p->next[temp[i]-'a']==NULL)
			p->next[temp[i]-'a']=new node;
		p=p->next[temp[i]-'a'];
	}
	if(p->id==0)
		p->id=num++;
}
int search(char*temp)
{
	node*p=root;
	int i,len=strlen(temp);
	for(i=0;i<len;i++)
		p=p->next[temp[i]-'a'];
	return p->id;
}
void make_set(int x)   
{   
        p[x]=x;   
        r[x]=1;   
} 
int find_set(int x)
{
	if(p[x]!=x)
		p[x]=find_set(p[x]);
	return p[x];
}
void Union(int x,int y)
{
	if(r[x]>=r[y])
	{
		p[y]=x;
		r[x]=r[x]+r[y];
	}
	else
	{
		p[x]=y;
		r[y]=r[y]+r[x];
	}
}
int main()
{
	while(scanf("%s %s",clr1,clr2)!=EOF)
	{
		insert(clr1);
		insert(clr2);
		int x1=search(clr1);
		int x2=search(clr2);
		rec[x1]++;
		rec[x2]++;
		if(p[x1]==0)
			make_set(x1);
		if(p[x2]==0)
			make_set(x2);
		Union(find_set(x1),find_set(x2));
	}
	int i=0,sum=0;
	for(i=1;i<num;i++)
	{
		if(rec[i]%2!=0)
			sum++;
		if(sum>2)
		{
			printf("Impossible\n");
			return 0;
		}
	}
	for(i=1;i<num;i++)
	{
		if(find_set(i)!=find_set(1))
		{
			printf("Impossible\n");
			return 0;
		}
	}
	printf("Possible\n");
	return 0;
}
posted on 2011-06-06 23:24  void-man  阅读(369)  评论(0)    收藏  举报