第一次接觸歐拉回路。雖然在離散數學裏學過,敲代碼仍是第一次。數組
本題是說端點顏色相同的兩根木棒可鏈接,可否將全部的木棒連成一條直線。spa
將顏色視爲節點v,將木棒視爲邊e,構成圖G。若是能找到一條一筆畫的路通過全部邊,那麼便符合條件。也就是判斷是不是歐拉回路。code
歐拉回路的條件是:blog
(1) 圖是連通的。數學
(2) 度數爲基數的點的個數是兩個,或者不存在。string
連通能夠經過用並查集判斷。度數能夠建一個數組保存當前點的度數。io
值得注意的是有全空的數據,此時應該輸出Possible。這點坑了我一下,在Discuss裏發現有人提出了,改一下就A了。class
#include <cstdio> #include <cstring> const int maxn=500010; int root[maxn]; int degree[maxn]; struct Node { int next[26]; int id; } dic[1000000]; int index=0; int id=0; int find(int x) { return root[x]?root[x]=find(root[x]):x; } bool union_set(int a,int b) { a=find(a); b=find(b); if(a==b) return false; root[b]=a; return true; } int insert(char* s) { int now=0; int len=strlen(s); for(int i=0;i<len;i++) { int next=s[i]-'a'; if(dic[now].next[next]==0) dic[now].next[next]=++index; now=dic[now].next[next]; } if(dic[now].id==0) dic[now].id=++id; return dic[now].id; } int main() { // freopen("in.txt","r",stdin); int num=1; char s1[20],s2[20]; while(~scanf("%s%s",s1,s2)) { int a=insert(s1); int b=insert(s2); degree[a]++; degree[b]++; if(union_set(a,b)) num++; } if(num==id || id==0) { int count=0; for(int i=1;i<=id;i++) if(degree[i]&1) { count++; if(count==3) break; } if(count==0 || count==2) { printf("Possible\n"); return 0; } } printf("Impossible\n"); }