字典树+欧拉回路+并查集
用map给字符串编号会超时。 用字典树给字符串编号要注意内存,尽量不要用递归的写法。木棒可能为0个。
并查集计算连通分量。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <vector>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int Maxn = 5e5+10;
const int INF = 0x3f3f3f3f;
struct Node {
int val;
struct Node *next[26];
Node () {
val = -1;
memset(next, NULL, sizeof(next));
}
} *root;
int deg[Maxn], pre[Maxn], n;
char col[20];
int idx(char c) { return c-'a'; }
int FindTree (Node *rt, char *s) {
Node *tmp = rt;
int pos = 0;
while(s[pos] != '\0') {
if(tmp->next[idx(s[pos])] == NULL) tmp->next[idx(s[pos])] = new Node();
tmp = tmp->next[idx(s[pos])];
pos++;
}
if(tmp->val == -1) tmp->val = n++;
return tmp->val;
}
void DelTree (Node *rt) {
for(int i = 0; i < 26; ++i) {
if(rt->next[i] == NULL) continue;
DelTree(rt->next[i]);
}
free(rt);
}
int Find(int x) {
if(pre[x] != x) pre[x] = Find(pre[x]);
return pre[x];
}
void union_(int x, int y) {
int xx = Find(x);
int yy = Find(y);
if(xx == yy) return;
pre[xx] = yy;
}
int main(void)
{
int ct = 0;
n = 0;
memset(deg, 0, sizeof(deg));
for(int i = 0; i < Maxn; ++i) pre[i] = i;
root = new Node();
while(scanf("%s", col) != EOF) {
int x = FindTree(root, col);
deg[x]++;
scanf("%s", col);
int y = FindTree(root, col);
deg[y]++;
union_(x, y);
}
int cnt = 0, odd = 0;
for(int i = 0; i < n; ++i) if(pre[i] == i) cnt++;
for(int i = 0; i < n; ++i) {
if(deg[i]&1) odd++;
}
if((cnt == 1 || cnt == 0) && (odd == 0 || odd == 2)) printf("Possible\n");
else printf("Impossible\n");
// DelTree(root);
return 0;
}
浙公网安备 33010602011771号