poj-2513-Colored Sticks-字典树trie / hash +并查集 欧拉回路

   

http://poj.org/problem?id=2513

   ..........一看到题。。试着用hash水一下。。wa

用map水一下TLE。。

好吧。。trie试一下。。。wa .wa .wa.....

好吧。。最后发现是自己傻逼了。。。

        窝一开始犯了傻逼错误,以为 直接 计算颜色出现的种数。。。奇数个数的颜色为0或2 就 合法。。然而这只是必要条件.....不是充分条件...........

         

       除了要奇数度数 为 0 或 2才能满足题目要求,还要【保证能联通】,  (后来发现这个东西叫欧拉回路)

联通的话 用个并查集判一下联通即可。。。

于是分别用hash、trie水了一遍


以下是用trie字典树做的 425ms

 //头文件    
double eps=0.000001; 
const ull mod= 2000007  ;  
const int maxnode = 5000000+5 ;   
int fa[5000000];
int deg[5000000];

struct trie
{
	int ch[maxnode][26];
	int val[maxnode];
	int sz;
	void init()
	{
		sz=1;
		val[0]=0;
		memset(ch[0],0,sizeof(ch[0]));
	}
	inline int idx(char c) {return c-'a';}
	
	void insert(char *s,int v)
	{
		int u=0,n=strlen(s),i;
		for (i=0;i<n;i++)
		{
			int c=idx(s[i]);
			if (!ch[u][c])
			{
				memset(ch[sz],0,sizeof(ch[sz]));
				val[sz]=0;
				ch[u][c]=sz++;
			}
			u=ch[u][c];
		}
		val[u]=v;//该单词出现一次
	}
	int query(char *s)
	{
		int u=0,n=strlen(s),i;
		for (i=0;i<n;i++)
		{
			int c=idx(s[i]);
			if (!ch[u][c]) return 0;
			else
				u=ch[u][c];
		}
		return val[u];
	}
};
int find(int x)
{
	if (fa[x]==x)
		return x;
	else
		return fa[x]=find(fa[x]);
}



trie tp; 
int main()
{ 
	tp.init();
	int i=0;
	for (i=1;i<=5000000;i++) fa[i]=i;
	char ss[30];
	int cnt=0;
	while(gets(ss))
	{ 
		int len=strlen(ss);
		for (i=0;i<len;i++)
		{
			if (ss[i]==' ')break;
		}
		ss[i]=0;
		int x=tp.query(ss);
		int y=tp.query(ss+i+1);
		if (!x)	tp.insert(ss,x=++cnt);
		if (!y)	tp.insert(ss+i+1,y=++cnt);
		deg[x]++;deg[y]++; 
		int fx= find(x);
		int fy=  find(y);
		if (fx!=fy) fa[fx]=fy;
	}
	int   one=0;
	for (i=1;i<=cnt;i++)
	{
		if (deg[i]%2)
			one++;
	}
	int flag=1;
	int k=find(1);
	for (i=1;i<=cnt;i++)
	{if (find(i)!=k) {flag=0;break;}}
	
	if (flag==1&&(one==2||one==0) )
		printf("Possible\n");
	else
		printf("Impossible\n");
	return 0;
	
}



  
以下是hash的代码
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
typedef unsigned __int64 ull; 
const double pi=acos(-1.0);
double eps=0.000001;
int n;
int  hash[273933+5];
const ull mod= 273933  ;  
   
char ss[30];
int fa[273933+5];
ull gethash(char *s ,ull p)
{
	ull tmp=0;
	int i,len=strlen(s);
	for (i=0;i<len;i++)
	{
		tmp=tmp*p+s[i];
	}
	return tmp;
}
  int find(int x)
  {
	  if (fa[x]==x)
		  return x;
	  else
		  return fa[x]=find(fa[x]);
  }

int que[273933],que_ok=0;
int main()
{ 
 
		int i=0;
	for (i=1;i<=273933;i++)
	fa[i]=i;
	int ok=0;
	while(gets(ss))
	{
		int len=strlen(ss);
		for (i=0;i<len;i++)
		{
			if (ss[i]==' ')break;
		}
		ss[i]=0; 
		ull ret=gethash(ss+i+1,239);
		int dd=ret%273933; 
		que[++que_ok]=dd;
	
		hash[dd]++;  

		int tmpd=dd;
		 ret=gethash(ss,239); 
		 dd=ret%273933; 
			que[++que_ok]=dd;
			hash[dd]++; 
		
		int fx=find(dd);
		int fy=find(tmpd);
		if (fx!=fy)
			fa[fx]=fy;
	}
	int one=0; 
	for (i=0;i<273933;i++)
	{
		if (hash[i]%2) one++;   
	}	 
	int flag=1; 
	int head=find(que[1]);
	for (i=1;i<=que_ok;i++)
	{
			if (find(que[i])!=head)  
			{flag=0;break;}
	} 
		if (flag==1&&(one==0||one==2)) 
		printf("Possible\n");
	else
		printf("Impossible\n");
	return 0;
	
}



你可能感兴趣的:(poj-2513-Colored Sticks-字典树trie / hash +并查集 欧拉回路)