POJ2513--Colored Sticks

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
判断是否是欧拉路。需要判断两个方面,一:图是否连通。可以用压缩路径的并查集。二:是否满足度数为奇数的点为0或者只有2个。
下面的做法是不判重的HASH~
 
 
44160K985MS
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
using namespace std;
int color[6000000];
int father[6000000];
int Hash(char *s)
{
	int key=0;
	int len=strlen(s);
	for(int i=0;i<len;i++)
	{
		key=(key*307+s[i])%5235367;
	}
	return key;
}
int find(int x)
{
	if(x==father[x])return x;
	father[x]=find(father[x]);
	return father[x];
}
void Union(int x,int y)
{
	int xx=find(x);
	int yy=find(y);
	father[xx]=yy;
}
int main()
{
	for(int i=0;i<=5235767;i++)
	{
		father[i]=i;
	}
	memset(color,0,sizeof(color));
	char str1[14],str2[14];
	while(scanf("%s%s",str1,str2)==2)
	{
		int h1=Hash(str1);
		int h2=Hash(str2);
		color[h1]++;color[h2]++;
		Union(h1,h2);
	}
	int sum=0;
		int zuzong;bool flag;
	for(int i=0;i<=5235367;i++)
	{
		if(color[i]&1)
		{
			sum++;
			if(sum>=3)goto L;
		}
	}
	for(int i=0;i<=5235367;i++)
	{
		if(color[i])
		{
			zuzong=find(i);
			break;
		}
	}
	flag=true;
	for(int i=0;i<=5235367;i++)
	{
		if(color[i]&&find(i)!=zuzong)
		{
			flag=false;
			goto L;
		}
	}
	L:
	if(flag&&(sum==0||sum==2))
	{
		printf("Possible\n");
	}
	else printf("Impossible\n");
}

 
判重的哈希:

   
   
27548K1625MS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
struct Word
{
	int sum;//出现的次数
	char str[12];
	int id;//这是第几种单词。并查集的时候要用到
}word[500008];
#define maxn 106541
vector <Word> ans[maxn+1];
int father[500008];
int Hash(char *s)
{
	int key=0,len=strlen(s);
	for(int i=0;i<len;i++)
	{
		key=(key*307+s[i])%106541;
	}
	return key;
}
int find(int x)
{
	if(x==father[x])return x;
	father[x]=find(father[x]);
	return father[x];
}
void Union(int x,int y)
{
	int xx=find(x);
	int yy=find(y);
	father[xx]=yy;
}
int main()
{
	int zuzong;bool liantong;
	for(int i=0;i<=500008;i++)
	{
		father[i]=i;
	}
	int k=0,t=0;
	while(scanf("%s%s",word[k].str,word[k+1].str)==2)
	{
		int h1=Hash(word[k].str);
		int h2=Hash(word[k+1].str);
		if(!ans[h1].size())
		{
			ans[h1].push_back(word[k]);
			word[k].id=t;
			ans[h1][0].id=t++;
			ans[h1][0].sum=1;
		}
		else
		{
			bool flag=false;
			for(int i=0;i<ans[h1].size();i++)
			{
				if(strcmp(ans[h1][i].str,word[k].str)==0)
				{
					ans[h1][i].sum++;
					word[k].id=ans[h1][i].id;
					flag=true;
					break;
				}
			}
			if(!flag)
			{
				ans[h1].push_back(word[k]);
				word[k].id=t;
				ans[h1][ans[h1].size()-1].id=t++;
				ans[h1][ans[h1].size()-1].sum=1;
			}
		}
		if(!ans[h2].size())
		{
			ans[h2].push_back(word[k+1]);
			ans[h2][0].sum=1;
			word[k+1].id=t;
			ans[h2][0].id=t++;
		}
		else
		{
			bool flag=false;
			for(int i=0;i<ans[h2].size();i++)
			{
				if(strcmp(ans[h2][i].str,word[k+1].str)==0)
				{
					ans[h2][i].sum++;
					word[k+1].id=ans[h2][i].id;
					flag=true;
					break;
				}
			}
			if(!flag)
			{
				ans[h2].push_back(word[k+1]);
				word[k+1].id=t;
				ans[h2][ans[h2].size()-1].sum=1;
				ans[h2][ans[h2].size()-1].id=t++;
			}
		}
		k+=2;
	}
	int jidu=0;
	for(int i=0;i<maxn;i++)
	{
		if(ans[i].size())
		{
			for(int j=0;j<ans[i].size();j++)
			{
				if(ans[i][j].sum&1)
				{
					jidu++;
					if(jidu>=3)goto L;
				}
			}
		}
	}
	for(int i=0;i<k;i+=2)
	{
		Union(word[i].id,word[i+1].id);
	}
	liantong=true;
	zuzong=find(0);
	for(int i=0;i<t;i++)
	{
		if(find(i)!=zuzong)
		{
			liantong=false;
			goto L;
		}
	}
L:
	if((jidu>=3||jidu==1)||!liantong)
	{
		printf("Impossible\n");
	}
	else printf("Possible\n");
}
 



Tire树:

       
       
 59060K516MS
/*
欧拉路径问题
*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 5000800
#define maxm 500080
int father[maxm],rank1[maxm],du[maxm];
int cnt,ant;
struct Node
{
	Node * pr[26];
	int id;
	/*Node()
	{
		for(int i = 0;i < 26;i++)
			pr[i] = NULL;
	}*/
}*root,memory[maxn];

Node * createnode()
{
	Node * p = &memory[ant++];
	for(int i = 0;i < 26;i++)
	{
		p -> pr[i] = NULL;
	}
	p ->id = 0;
	return p;
}

int idx(char c)
{
	return c - 'a';
}

int insert(char * s)
{
	int len = strlen(s);
	Node * p = root;
	for(int i = 0;i < len;i++)
	{
		int u = idx(s[i]);
		if(p -> pr[u] == NULL)
		{
			p -> pr[u] = createnode();
		}
		p = p -> pr[u];
	}
	if(p -> id == 0)
	{
		p -> id = cnt++;
	}
	return p -> id;
}

void init(int n)
{
	for(int i = 0;i < n;i++)
	{
		father[i] = i;
	}
	memset(rank1,0,sizeof(rank1));
	memset(du,0,sizeof(du));
}

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

void Union(int a,int b)
{
	int fa = find(a),fb = find(b);
	if(fa == fb)	return;
	if(rank1[fa] > rank1[fb])	
	{
		father[fb] = fa;
	}
	else if(rank1[fa] < rank1[fb])
	{
		father[fa] = fb;
	}
	else 
	{
		father[fb] = fa;
		rank1[fa]++;
	}
}

int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	cnt = 1,ant = 0;
	char str1[12],str2[12];
	init(maxm);
	root = createnode();
	while(scanf("%s%s",str1,str2)!=EOF)
	{
		int a = insert(str1);
		int b = insert(str2);
		Union(a,b);
		du[a]++;du[b]++;
	}
	int src = find(1);
	bool flag = true;
	for(int i = 1;i < cnt;i++)
	{
		if(find(i) != src)
		{
			flag = false;
			break;
		}
	}
	//到这里说明连通
	int jinum = 0;
	for(int i = 1;i < cnt;i++)
	{
		if(du[i] & 1) jinum++;
	}
	if(flag && (jinum == 0 || jinum == 2))	printf("Possible\n");
	else printf("Impossible\n");
}










/*
并查集判连通+欧拉回路
*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 5008000
#define maxm 500800
int father[maxm],du[maxm];
int rank1[maxm];
char str1[14],str2[14];
int find(int x)
{
	if(x == father[x])	return x;
	return father[x] = find(father[x]);
}


void Union(int a,int b)
{
	int fa = find(a);
	int fb = find(b);
	if(fa == fb)	return;
	if(rank1[fa] > rank1[fb])
	{
		father[fb] = fa;
	}
	else if(rank1[fa] == rank1[fb])
	{
		father[fb] = fa;
		rank1[fa]++;
	}
	else father[fa] = fb;
}


struct Trie
{
	int first[maxn],nxt[maxn];
	int ch[maxn],val[maxn];
	int cnt,index;
	void init()
	{
		index = 0;
		cnt = 1;
		val[0] = 0;
		first[0] = -1;
	}


	int insert(char * s)
	{
		int u = 0;
		int len = strlen(s);
		for(int i = 0;i < len;i++)
		{
			int id = s[i];
			int j;bool flag = false;
			for(j = first[u];j != -1;j = nxt[j])
			{
				if(ch[j] == id)
				{
					flag = true;
					break;
				}
			}
			if(!flag)
			{
				ch[cnt] = id;
				val[cnt] = 0;
				first[cnt] = -1;
				nxt[cnt] = first[u];
				first[u] = cnt++;
			}
			if(flag)	u = j;
			else u = cnt-1;
		}
		if(!val[u])	val[u] = ++index;
		return val[u];
	}
}trie;


int main()
{
	//freopen("in.txt","r",stdin);
	for(int i = 1;i < maxm;i++)
	{
		father[i] = i;
		du[i] = rank1[i] = 0;
	}
	trie.init();
	while(scanf("%s",str1)!=EOF)
	{
		scanf("%s",str2);
		int a = trie.insert(str1);
		int b = trie.insert(str2);
		Union(a,b);
		du[a]++;	du[b]++;
	}
	int zuzong = find(1);
	bool flag = true;
	for(int i = 1;i <= trie.index;i++)	
		if(find(i) != zuzong)	
		{
			flag = false;
			break;
		}
	int jinum = 0;
	for(int i = 1;i <= trie.index;i++)
		if(du[i] & 1) jinum++;
	if((jinum == 0 || jinum == 2) && flag)
		puts("Possible");
	else puts("Impossible");
	return 0;
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值