/*
思路:類似圖論中“一筆畫”問題,兩根木棒的相連接的端點是一樣的顏色,(a,b)--(b,c)--(c, d)....
方法:trie樹+并查集, 利用trie樹建立字符串和某一個節點的映射,并將這些和字符串構成映射的節點建成圖, 用并查集判斷圖的連通
*/
1 #include<iostream> 2 #include<cstdio>3 #include<cstring>4 #define N 2500005*25 using namespace std;6 int f[N];7 int indgr[N];8 int trie[N][26];9 int nodeNum, pre, cnt, oddDgr, root;
10 int getFather(int x)//并查集尋找父親節點,壓縮路徑
11 {
12 return x == f[x] ? x : f[x]=getFather(f[x]);
13 }
14
15 void Union(int a, int b)//并查集的合并
16 {
17 int fa=getFather(a), fb=getFather(b);
18 if(fa!=fb)
19 f[fa]=fb;
20 }
21
22 int main()
23 {
24 char color[15];
25 int i;
26 for(i=0; i<N; ++i)
27 f[i]=i;
28 while(scanf("%s", color)!=EOF)
29 {
30 cnt++;
31 int cur=0, L=strlen(color);
32 for(i=0; i<L; ++i)
33 {
34 int k=color[i]-'a';
35 if(!trie[cur][k])
36 trie[cur][k]=++nodeNum;
37 cur=trie[cur][k];
38 }
39 ++indgr[cur];
40 if(cnt%2) pre=cur;
41 else
42 Union(pre, cur);
43 }
44 for(i=0; i<=nodeNum; ++i)
45 {
46 if(indgr[i]&1) ++oddDgr;
47 if(indgr[i] && f[i]==i) ++root;
48 if(oddDgr>2 || root>1) break;
49 }
50 if((oddDgr==0 || oddDgr==2) && root==1 || oddDgr==0 && root==0)//注意空樹的情況下是輸出Impossible, 開始就是錯在了這里
51 printf("Possible\n");
52 else printf("Impossible\n");
53 return 0;
54 }