题目链接

字典树+欧拉回路+并查集

用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;
}