Files
python/TangDou/AcWing/EulerPath/POJ2513_4.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

71 lines
2.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <iostream>
#include <vector>
#include <cstring>
#include <string>
using namespace std;
const int N = 500010;
int p[N]; // 并查集数组
int d[N]; // 度
char str1[15], str2[15]; // 两个字符串
// int b[N]; // 记录字符串(对应的HASH值)是否出现过,是桶的概念
int id[N], n; // 用于离散化,根据p是否出现,决定是否为其分配新的节点编号,有旧的使旧的,有新的创建后使新的
int idx; // 创建Trie树时的游标
int tr[N][26]; // Trie树
/*
如果平均字符串长度是10,那么在最坏的情况下,Trie树中最多可能有500000 * 10 = 5000000个节点。
这是因为在最坏的情况下,每个字符串都不共享任何前缀,因此每个字符串的每个字符都会在Trie树中创建一个新的节点。
需要注意的是,这是一个上界,实际的节点数量可能会少于这个值,因为许多字符串可能会共享一些前缀,这些前缀在Trie树中只会被存储一次。
*/
int insert(string str) { // 插入字典树并返回结尾字符节点编号
int p = 0;
for (int i = 0; i < str.size(); i++) {
int u = str[i] - 'a'; // 映射成0~25,本题只有小写字母
if (!tr[p][u]) tr[p][u] = ++idx;
p = tr[p][u];
}
/* 如上面的论述结果,idx:Trie树中有很多的节点,可每个字符串最后的终点只有1个
我们需要知道我们在心中创建的图有多少个节点,一般用n表示,如果我们直接使用Trie树中的p,虽然在数据范围内不会越界,但在1~p之间,肯定存在无效的节点,这是我们不能接受的,
办法就是直接离散化,只保留有用的节点,重新编号:id[N]+cnt
*/
if (!id[p]) id[p] = ++n; // 节点编号
return id[p];
}
// 并查集
int find(int x) {
if (x == p[x]) return x;
return p[x] = find(p[x]);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("POJ2513.in", "r", stdin);
#endif
for (int i = 0; i < N; i++) p[i] = i;
while (~scanf("%s%s", str1, str2)) {
int a = insert(str1), b = insert(str2); // 利用Trie树找出字符串的HASH值,其它与纯字符串131进制的代码一致
d[a]++, d[b]++;
if (find(a) != find(b)) p[find(a)] = find(b);
}
int odd = 0, cnt = 0;
for (int i = 1; i <= n; i++) {
if (p[i] == i) cnt++;
if (d[i] % 2) odd++;
}
int flag = 1;
if ((odd != 0 && odd != 2) || cnt != 1) flag = 0;
if (n == 0) flag = 1;
if (flag)
puts("Possible");
else
puts("Impossible");
return 0;
}