并查集Union-Set: 使用rank数组
Trie树
欧拉图
注意:使用map容器会超时
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define M 500005
int pre[M];
int rank[M];
int deg[M];
int N;
struct trie
{
int color;
trie *next[26];
trie()
{
color=0;
memset(next,0,sizeof(next));
}
}*root;
int insert(trie *p,char str[])
{
int i;
for(i=0;str[i]!='\0';i++)
{
int s=str[i]-'a';
if(p->next[s]==NULL)
{
p->next[s]=new trie;
}
p=p->next[s];
if(str[i+1]=='\0')
{
if(p->color==0)
{
p->color=++N;
}
deg[p->color]++;
return p->color;
}
}
return 0;
}
void init()
{
int i;
for(i=1;i<M;i++)
{
pre[i]=i;
rank[i]=0;
}
}
int find(int x)
{
if(x!=pre[x])
{
pre[x]=find(pre[x]);
}
return pre[x];
}
bool isConnected()
{
int i;
for(i=2;i<=N;i++)
{
if(find(i)!=find(i-1))
{
return false;
}
}
return true;
}
void unionOp(int x,int y)
{
if(rank[x]<rank[y])
{
pre[x]=pre[y];
}
else if(rank[x]>rank[y])
{
pre[y]=pre[x];
}
else
{
pre[y]=pre[x];
rank[x]++;
}
}
bool cal()
{
int oddDeg=0;
if(!isConnected())
{
return false;
}
int i;
for(i=1;i<=N;i++)
{
if(deg[i]%2!=0)
{
oddDeg++;
}
if(oddDeg>2)
{
return false;
}
}
return true;
}
void read()
{
char c1[11],c2[11];
int x,y;
N=0;
root=new trie;
memset(deg,0,sizeof(deg));
init();
while(~scanf("%s%s",c1,c2))
{
x=insert(root,c1);
y=insert(root,c2);
unionOp(x,y);
}
}
int main()
{
read();
if(cal())
{
printf("Possible\n");
}
else
{
printf("Impossible\n");
}
return 0;
}