POJ/PKU 2513 并查集+字典树+欧拉回路

 
Colored Sticks
Time Limit: 5000MS   Memory Limit: 128000K
Total Submissions: 20750   Accepted: 5482

Description

You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a straight line such that the colors of the endpoints that touch are of the same color?

Input

Input is a sequence of lines, each line contains two words, separated by spaces, giving the colors of the endpoints of one stick. A word is a sequence of lowercase letters no longer than 10 characters. There is no more than 250000 sticks.

Output

If the sticks can be aligned in the desired way, output a single line saying Possible, otherwise output Impossible.

Sample Input

blue red
red violet
cyan blue
blue magenta
magenta cyan

Sample Output

Possible

Hint

Huge input,scanf is recommended.

Source

The UofA Local 2000.10.14
 
 
要仔细看题,木棍不仅仅只是可以一个方向放置,还可以倒过来,所以简单的说,这个题是一个无向图的欧拉回路判断
但是直接用map要超时。。我先开始就这样TLE了。后来看了下后面的discuss,发现要用字典树
于是又自己手动写了个字典树。
 
所以综上,我们需要:
1、字典树对每一个字符串进行标号
2、并查集判断整个图是否连通
3、判断无向图的欧拉回路是否存在
 
我的代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define maxn 500005

using namespace std;

struct node
{
	int num;
	node *next[26];
	void init();
};
node *root;
int father[maxn];
int temp[maxn];
int sum[maxn];
int cnt=0;

void node::init()
{
	this->num=0;
}

int find(int p)
{
	if(father[p]==p)
		return p;
	return father[p]=find(father[p]);
}

void Union(int a,int b)
{
	int x,y;
	x=find(a);
	y=find(b);
	if(x!=y)
		father[x]=y;
}

void init()
{
	root= new node;
	int i;
	for(i=0;i<26;i++)
		root->next[i]=NULL;
	root->init();
}

int search(char *s)
{
	int i,len=strlen(s),j;
	node *p,*t;
	p=root;
	for(i=0;i<len;i++)
	{
		if(p->next[s[i]-'a']==NULL)
		{
			t=new node;
			for(j=0;j<26;j++)
				t->next[j]=NULL;
			t->init();
			p->next[s[i]-'a']=t;
		}
		p=p->next[s[i]-'a'];
	}
	if(p->num==0)
	{
		cnt++;
		return p->num=cnt;
	}
	else
		return p->num;
}

int main()
{
	int i,a,b;
	char s1[15],s2[15];
	memset(sum,0,sizeof(sum));
	for(i=1;i<=maxn;i++)
		father[i]=i;
	init();
	while(scanf("%s%s",s1,s2)!=EOF)
	{
		a=search(s1);
		b=search(s2);
		Union(a,b);
		sum[a]++;
		sum[b]++;
	}
	int NUM=0;
	for(i=1;i<=cnt;i++)
		if(father[i]==i)
			NUM++;
	if(NUM>1)
	{
		printf("Impossible\n");
		return 0;
	}
	NUM=0;
	for(i=1;i<=cnt;i++)
		if(sum[i]&1)
			NUM++;
	if(NUM==0||NUM==2)
		printf("Possible\n");
	else
		printf("Impossible\n");
	return 0;
}

你可能感兴趣的:(POJ/PKU 2513 并查集+字典树+欧拉回路)