题意:
给一堆小棒,每跟小棒上有两种颜色,颜色相同的两端可以连起来,问所有小棒是否可以练成一条线。
分析:
无向图是否存在欧拉路径问题,这题主要是与输入做斗争,输入的字符串用map水的话会超时,只能老老实实写字典树。
代码:
//poj 2513
//sepNINE
#include <iostream>
#include <string>
using namespace std;
const int maxN=500024;
int d[maxN];
int n,f[maxN];
int find(int u)
{
return f[u]==u?u:f[u]=find(f[u]);
}
struct TrieNode
{
bool flag;
int ids;
TrieNode *next[27];
TrieNode(){
flag=false;
ids=0;
memset(next,0,sizeof(next));
}
}root;
int getId(char *s)
{
TrieNode *p=&root;
int len=0;
while(s[len]!='\0'){
int index=s[len++]-'a';
if(!p->next[index])
p->next[index]=new TrieNode;
p=p->next[index];
}
if(p->flag)
return p->ids;
p->flag=true;
p->ids=++n;
return p->ids;
}
int judge()
{
int i;
for(i=1;i<=n;++i)
f[i]=find(i);
for(i=2;i<=n;++i)
if(f[i]!=f[i-1])
return 0;
return 1;
}
int main()
{
int i,x,ans=0;
memset(d,0,sizeof(d));
char a[12];
char b[12];
n=0;
for(i=1;i<=maxN;++i)
f[i]=i;
while(cin>>a>>b){
int u=getId(a),v=getId(b);
++d[u];
++d[v];
int pa=find(u);
int pb=find(v);
if(pa!=pb)
f[pa]=pb;
}
for(x=0,i=1;i<=n;++i){
if(d[i]%2==1)
++x;
if(x>2)
break;
}
if((x==2||x==0)&&judge()==1)
ans=1;
if(ans==1)
printf("Possible");
else
printf("Impossible");
return 0;
}