並查集+歐拉回路+字典樹 Colored Sticks POJ 2513

輸入多組數據,每組數據兩種顏色,表示一根木頭兩端的顏色,現在要將這些木頭相連,要求相連部分顏色相同,問能否全部連通

提示

1)一個要判斷所有的木頭是否在一個集合中,即是否能相連

2)判斷一種顏色出現的數量

3)一棵樹如果只有0或2個點出現次數爲奇數,則樹可以一筆畫成

#include <stdio.h>
#include <string.h>
#define maxn 500005
int tot;
int f[maxn];
int num[maxn];
struct trie
{
	trie *next[30];
	int id;
	trie()
	{
		for(int i=0;i<30;i++)
			next[i]=NULL;
		id=0;
	}
};
trie *root;
int find(int i)
{
	if(i==f[i])
		return f[i];
	f[i]=find(f[i]);
	return f[i];
}
int build(char *str)           //建立字典樹
{
	int len=strlen(str);
	trie *p=root;
	for(int i=0;i<len;i++)
	{
		int id=str[i]-'a';
		if(p->next[id]==NULL)
			p->next[id]=new trie;
		p=p->next[id];
	}
	if(p->id==0)
		p->id=tot++;
	return p->id;
}
int main()
{
	char str1[50];
	char str2[50];
	int a,b;
	int fr,ed;
	int i;
	for(i=0;i<maxn;i++)
	{
		f[i]=i;
		num[i]=0;
	}
	tot=1;
	int tt=0,ff=0;
	root=new trie;
	while(scanf("%s%s",str1,str2)!=-1)
	{
		a=build(str1);
		b=build(str2);
		fr=find(a);
		ed=find(b);
		if(fr!=ed)
			f[fr]=ed;  //集合
		num[a]++;         //統計出現次數
		num[b]++;
	}
	for(i=1;i<tot;i++)
		if(num[i]%2==1)
			tt++;
	for(i=1;i<tot;i++)
		if(f[i]==i)
			ff++;
	if(((tt==0)||(tt==2))&&(ff==1||ff==0))
		printf("Possible\n");
	else
		printf("Impossible\n");
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章