并查集+欧拉回路+字典树 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;
}


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