用Trie树记录单词,然后再用度数判定
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const double PI = acos(-1.0);
template <class T> inline T MAX(T a, T b){if (a > b) return a;return b;}
template <class T> inline T MIN(T a, T b){if (a < b) return a;return b;}
const int N = 111;
const int M = 11111;
const LL MOD = 1000000007LL;
const int dir[4][2] = {1, 0, -1, 0, 0, -1, 0, 1};
const int INF = 0x3f3f3f3f;
int n, cnt;
int d[550000], p[550000];
struct node
{
int next[30], val;
inline void cle()
{
memset(next, -1, sizeof (next));
val = -1;
}
}edge[5500000];
int Find(char s[])
{
int j, i = 0, p = 0;
while (s[i])
{
j = s[i] - 'a';
if (edge[p].next[j] != -1)
{
p = edge[p].next[j];
}
else return -1;
i++;
}
return edge[p].val;
}
int insert(char s[])
{
int i, j, p;
p = i = 0;
while (s[i])
{
j = s[i] - 'a';
if (edge[p].next[j] != -1)
{
p = edge[p].next[j];
}
else
{
edge[cnt].cle();
edge[p].next[j] = cnt++;
p = edge[p].next[j];
}
i++;
}
edge[p].val = ++n;
return n;
}
void Union(int a, int b)
{
int temp = p[a] + p[b];
if (p[a] < p[b])
{
p[b] = a;
p[a] = temp;
}
else
{
p[a] = b;
p[b] = temp;
}
}
int Find(int x)
{
if (p[x] < 0) return x;
else return Find(p[x]);
}
int main()
{
char str1[20], str2[20];
memset(p, -1, sizeof(p));
memset(d, 0, sizeof(d));
int i, a, b, x, y, flag = 1, have = 0;
n = cnt = 0;
edge[cnt++].cle();
while (scanf("%s%s", str1, str2) != EOF)
{
have = 1;
a = Find(str1); b = Find(str2);
if (a == -1) a = insert(str1);
if (b == -1) b = insert(str2);
d[a]++; d[b]++;
x = Find(a); y = Find(b);
if (x != y) Union(x, y);
}
int num = 0;
for (i = 1; i <= n; ++i)
{
if (p[i] < 0)
{
num++;
if (num > 1)
{
flag = 0;
break;
}
}
}
num = 0;
if (flag)
{
for (i = 1; i <= n; ++i)
{
if (d[i] % 2) num++;
}
}
if ((flag || !have) && ((num == 2 || num == 0))) printf("Possible\n");
else printf("Impossible\n");
getchar(); getchar();
return 0;
}