這道題可以直接看出是用歐拉通路來做,但是資料特別大,只能想辦法壓縮資料。所以用Trie樹來儲存幾萬種顏色,並給這些顏色標記為相應的結點。
下面是代碼:
#include<stdio.h>#include<string.h>#define maxn 510000int ch[maxn][26];int val[maxn];int degree[maxn];int f[maxn];int cnt;int ID;char s1[11],s2[11];void initi(){ for(int i = 0; i < maxn; i++) f[i] = i; memset(ch[0],0,sizeof(ch[0])); ID = 0; cnt = 1;}int find_father(int x){ if(x != f[x]) { f[x] = find_father(f[x]); } return f[x];}void union_node(int x,int y){ x = find_father(x); y = find_father(y); if(x != y) f[x] = y;}void insert_Trie(char *s){ int u = 0; while(*s) { int id = *s - 'a'; if(ch[u][id] == 0) { memset(ch[cnt],0,sizeof(ch[cnt])); val[cnt] = -1; ch[u][id] = cnt++; } u = ch[u][id]; s++; } val[u] = ID;}int get_id(char *s){ int u = 0; while(*s) { int id = *s - 'a'; if(ch[u][id] == 0) return -1; u = ch[u][id]; s++; } if(val[u] >= 0) return val[u]; return -1;}void solve(){ bool ok = true; int i; for(i = 0; !degree[i]; i++); for(int j = i + 1; j < ID; j++) { if(degree[j] && find_father(j) != find_father(i)) { ok = false; break; } } int flag = 0; if(ok) { for(int j = 0; j < ID; j++) { if(degree[j] %2 != 0) flag++; if(flag > 2) { ok = false; break; } } } if(ok && (flag == 2 || flag == 0) ) printf("Possible\n"); else printf("Impossible\n");}int main(){ initi(); while(scanf("%s %s",s1,s2) == 2) { int u = get_id(s1); int v = get_id(s2); if(u == - 1) insert_Trie(s1),u = ID++; if(v == -1) insert_Trie(s2),v = ID++; union_node(u,v); degree[u]++; degree[v]++; } solve(); return 0;}