题目链接:http://poj.org/problem?id=2513
题目大意:有n条木棒,没条木棒两端各有一种颜色,木棒之间可以连接当且仅当连接端的颜色相同,让判断对于给出的若干木棒,能否全部连接起来。
分析:以每种颜色为顶点建图,要想所有木棒都连接起来,即找出该图的一条欧拉路径。对于每种颜色,我们需要一一对应一个数字,我用map写了一个,果然TLE了,毕竟数据量还是不小的,改为用Tire树还跑了1280MS,要是把存储结构有链表换成数组模拟应该会快一些。
实现代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
using namespace std;
const int maxn=500005;
int ind[maxn];
int par[maxn],ran[maxn];
int cnt;
void init()
{
for(int i=0;i<maxn;i++)
{
par[i]=i;
ran[i]=1;
}
}
int Find(int x)
{
if(par[x]!=x) return par[x]=Find(par[x]);
return x;
}
void Union(int a,int b)
{
int x=Find(a);
int y=Find(b);
if(x==y) return ;
par[x]=y;
}
typedef struct node
{
bool terminal;
struct node *nex[26];
int id;
}tire;
tire *creat()
{
tire *p=new tire;
for(int i=0;i<26;i++)
p->nex[i]=NULL;
p->terminal=false;
p->id=0;
return p;
}
int insert(tire *root,char *str)
{
tire *p=root;
int i=0;
while(str[i]!='\0')
{
int x=str[i]-'a';
if(p->nex[x]==NULL)
p->nex[x]=creat();
p=p->nex[x];
i++;
}
if(p->terminal) return p->id;
else
{
p->terminal=true;
p->id=cnt++;
return p->id;
}
}
void del(tire *root)
{
for(int i=0;i<26;i++)
if(root->nex[i]!=NULL)
del(root->nex[i]);
free(root);
}
int main()
{
char str1[15],str2[15];
init();
cnt=0;
tire *root=creat();
memset(ind,0,sizeof(ind));
while(~scanf("%s%s",str1,str2))
{
int u=insert(root,str1);
int v=insert(root,str2);
ind[u]=!ind[u];
ind[v]=!ind[v];
Union(u,v);
}
int sum_par=0,sum_ind=0;
for(int i=0;i<cnt;i++)
{
//printf("par[%d]=%d\n",i,par[i]);
if(par[i]==i) sum_par++;
if(ind[i]&1) sum_ind++;
}
//printf("%d %d\n",sum_par,sum_ind);
if(sum_par>1)
puts("Impossible");
else
{
if(sum_ind==0||sum_ind==2)
puts("Possible");
else puts("Impossible");
}
return 0;
}