第一眼以为要建图去跑,但马上反应过来可以直接判度数就好
除此之外,还要判图是否联通,用并查集解决
最后,对颜色编号,因为在Trie的分类下看到的,所以直接拿红书板子敲了一个
(250000个棍子,5000000个颜色,数组开小WA了一发)
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 500100;
struct Trie
{
int tot,root,child[maxn][26],cnt;
int fa[maxn];
int flag[maxn],p[maxn];
Trie()
{
memset(child[1],0,sizeof(child[1]));
memset(flag,0,sizeof(flag));
memset(p,0,sizeof(p));
root = tot = 1;
cnt = 0;
}
int insert(const char *str)
{
int *cur = &root;
for(const char *pp = str; *pp; pp++)
{
cur = &child[*cur][*pp - 'a'];
if(*cur == 0)
{
*cur = ++tot;
memset(child[tot],0,sizeof(child[tot]));
flag[tot] = false;
}
}
if(!flag[*cur])
{
flag[*cur] = ++cnt;
fa[cnt] = cnt;
}
p[flag[*cur]]++;
return flag[*cur];
}
int getfa(int x)
{
if(x == fa[x])
return x;
fa[x] = getfa(fa[x]);
return fa[x];
}
void merge(int x,int y)
{
int fx = getfa(x);
int fy = getfa(y);
fa[fx] = fy;
}
}trie;
char str1[11],str2[11];
int x,y,father = 0;
bool ans;
int main()
{
while(~scanf("%s %s",str1,str2))
{
x = trie.insert(str1);
y = trie.insert(str2);
trie.merge(x,y);
}
int cnt = 0;
for(int i = 1; i <= trie.cnt; i++)
if(trie.p[i] & 1)
cnt++;
if(cnt == 0 || cnt == 2)
ans = true;
else
ans = false;
for(int i = 1; i <= trie.cnt; i++)
{
x = trie.getfa(i);
if(!father)
father = x;
else
{
if(father != x)
{
ans = false;
break;
}
}
}
printf("%s\n",ans ? "Possible" : "Impossible");
return 0;
}