题目链接:http://poj.org/problem?id=2513
思路:用字典树将每个单词映射成点,其他的就和sgu101一样了
sgu 101 链接:http://blog.csdn.net/u013649253/article/details/39781437
code:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=950100;
const int maxm=20;
int du[maxn],cnt;
class Trie
{
public:
int flag;
Trie* next[26];
Trie()
{
flag=-1;
memset(next,0,sizeof(next));
}
}root;
Trie * Find(char *C)
{
Trie*p=&root;
for(int i=0;i<strlen(C);i++){
int index=C[i]-'a';
if(!p->next[index]) p->next[index]=new Trie;
p=p->next[index];
}
return p;
}
int insert(char *C)
{
Trie*p=Find(C);
if(p->flag==-1) p->flag=cnt++;
return p->flag;
}
int par[maxn],num[maxn];
void init(int n_)
{
for(int i=0;i<=n_;i++){
par[i]=i;
num[i]=1;
}
}
int Find(int x)
{
if(par[x]==x) return x;
return par[x]=Find(par[x]);
}
void unite(int x,int y)
{
x=Find(x);
y=Find(y);
if(num[x]<num[y]){
par[x]=y;
num[y]+=num[x];
}
else{
par[y]=x;
num[x]+=num[y];
}
}
bool same(int x,int y)
{
return Find(x)==Find(y);
}
int main()
{
int s,t,nn,cnt1,cnt2;
char c1[maxm],c2[maxm];
memset(du,0,sizeof(du));
nn=cnt=0;
init(950100);
while(scanf("%s %s",c1,c2)!=EOF){
s=insert(c1);
t=insert(c2);
du[s]++;
du[t]++;
if(!same(s,t)) unite(s,t);
}
if(cnt==0) printf("Possible\n");
else if(num[Find(0)]!=cnt){
printf("Impossible\n");
}
else{
cnt1=cnt2=0;
for(int i=0;i<cnt;i++){
if(du[i]%2==0) cnt1++;
else cnt2++;
}
if((cnt2==2&&cnt1==cnt-cnt2)||(cnt1==cnt)) printf("Possible\n");
else printf("Impossible\n");
}
return 0;
}