题目大意:给你两段有颜色的木棒,只有相同的颜色才能连接起来,问你最后给你的木棒最后能不能拼成一根长木棒。
解题思路:这里字典树只是返回了不同颜色的编号,用map<string,int>也是可以的,我们可以记录每个颜色的度,一个木棒的两个颜色可以相连,所以这里可以用并查集将不同的颜色并起来,最后如果,有颜色的祖先和其他不一样,那肯定不能连起来,反之那就要判断欧拉路径 了,如果奇数度的点为0或者2,那这个图就可以一笔走完,即可以连接成一根木棒。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#include<sstream>
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int maxn=2e6+5;
int tree[maxn][30],sum[maxn];
int vis[maxn],num[maxn];
int tot=0,cnt=0;
int f[maxn],r[maxn];
int add(char *s) {
int root=0,id,len=strlen(s);
for(int i=0; i<len; ++i) {
id=s[i]-'a';
if(!tree[root][id]) tree[root][id]=++tot;
root=tree[root][id];
}
if(!vis[root]) vis[root]=++cnt;
return vis[root];
}
void init() {
for(int i=0; i<maxn; ++i) {
f[i]=i;
r[i]=0;
}
}
int find(int x) {
if(x=f[x]) return f[x];
else return f[x]=find(f[x]);
}
void unite(int x,int y) {
x=find(x);
y=find(y);
if(x==y) return ;
if(r[x]<r[y]) f[x]=y;
else {
f[y]=x;
if(r[x]==r[y]) r[y]++;
}
}
char s1[20],s2[20];
int main() {
int tp1,tp2;
init();
while(scanf("%s%s",s1,s2)!=EOF) {
tp1=add(s1);
tp2=add(s2);
num[tp1]++;
num[tp2]++;
unite(tp1,tp2);
}
int flag=find(1),tt=0;
for(int i=1; i<=cnt; ++i) {
if(num[i]%2) tt++;
if(find(i)!=flag) {
cout<<"Impossible"<<endl;
return 0;
}
}
if(tt==0||tt==2) cout<<"Possible"<<endl;
else cout<<"Impossible"<<endl;
return 0;
}