综合题,长知识,锻炼编码能力,锻炼心理承受能力...
思路:trie树记录每个单词的id,并查集判断无向图联通
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define NIL NULL
#define maxn 500005
int f[500005],d[500005],cnt,set;
struct NodeType{
int id;
bool flag;
NodeType *Child[26];
NodeType()
{
id=-1;
flag=false;
for(int i=0;i<26;++i)
Child[i]=NIL;
}
};
NodeType *Root;
void Init()
{
Root=new NodeType();
int i;
for(i=0;i<=maxn;++i)
f[i]=i;
memset(d,0,sizeof(d));
cnt=0;
set=0;
}
void TrieInsert(char chars[])
{
int i,len=strlen(chars),index;
NodeType *t=Root;
for(i=0;i<len;++i)
{
index=chars[i]-'a';
if(t->Child[index]==NIL)
{
t->Child[index]=new NodeType();
}
t=t->Child[index];
}
if(t->flag==false)
{
cnt++;
set++;
t->flag=true;
t->id=cnt;
}
}
int TrieFind(char chars[])
{
int i,len=strlen(chars),index;
NodeType *t=Root;
for(i=0;i<len;++i)
{
index=chars[i]-'a';
t=t->Child[index];
}
return t->id;
}
int Find(int id)
{
if(f[id]==id)
return id;
else
return f[id]=Find(f[id]);
}
void Merge(int id1,int id2)
{
if(id1==id2)
return ;
else if(Find(id1)==Find(id2))
return ;
else
{
set--;
f[f[id2]]=f[id1];
}
}
int main()
{
Init();
char input[50],A[15],B[15];
int i,j,id1,id2,even=0;
while(gets(input))
{
for(i=0;input[i]!=' ';++i)
A[i]=input[i];
A[i++]='\0';
for(j=0;input[i]!='\0';++i,++j)
B[j]=input[i];
B[j]='\0';
TrieInsert(A);
TrieInsert(B);
id1=TrieFind(A),id2=TrieFind(B);
d[id1]++,d[id2]++;
Merge(id1,id2);
}
if(set<=1)
{
for(i=1;i<=cnt;++i)
if(d[i]%2!=0)
even++;
if(even==2||even==0)
printf("Possible\n");
else
printf("Impossible\n");
}
else
printf("Impossible\n");
return 0;
}