#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <algorithm>
#include <math.h>
#include <stack>
using namespace std;
int cnt = 1, x, y, deg[500001], f[500001];
struct node
{
int num; //每一个字符的个数
node *next[26];
node()
{
int i;
for (i = 0; i < 26; i++) //初始化
{
next[i] = NULL;
}
num = 0;
}
};
node *root;
int search(char *s)
{
node *p = root;
int len = strlen(s), i;
for (i = 0; i < len; i++)
{
int k = s[i] - 'a';
if (p->next[k] == NULL)
return 0;
p = p->next[k];
}
return p -> num; // 这一串字符的用cnt代表的数
}
void Insert(char *s)
{
node *p = root;
int len = strlen(s), i;
for (i = 0; i < len; i++)
{
int k = s[i] - 'a';
if (p->next[k] == NULL)
p->next[k] = new node;
p = p->next[k];
}
p -> num = cnt++;
}
int getf(int u) //并查集
{
if (u == f[u])
return u;
else
{
f[u] = getf(f[u]);
return f[u];
}
}
void merge(int u, int v) //并查集
{
int t1 = getf(u), t2 = getf(v);
if (t1 != t2)
{
f[t2] = t1;//他的头子的标号
}
}
bool judge()
{
int i, sum = 0;
for (i = 1; i < cnt; i++)
{
if (getf(i) != getf(1))
return 0;
if (deg[i] % 2)
sum++;
}
if (sum == 0 || sum == 2)
return true;
else
return false;
}
int main()
{
char s1[15], s2[15];
int i;
for (i = 0; i < 500000; i++)
f[i] = i;
root = new node;
while (~scanf("%s %s", s1, s2))
{
x = search(s1);
y = search(s2);
if (x == 0)
{
Insert(s1);
x = cnt - 1;
}
if (y == 0)
{
Insert(s2);
y = cnt - 1;
}
deg[x]++, deg[y]++; //度数加一
merge(x, y);
}
if (judge())
printf("Possible\n");
else
printf("Impossible\n");
return 0;
}
借鉴:https://www.iteye.com/blog/gzhu-101majia-1355218
关键就是得理解num的含义!!表示这个字符串用cnt代表的数
再来一波二维数组的做法
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <algorithm>
#include <math.h>
#include <stack>
using namespace std;
//把dp订正了一下 500005 -> 1000000
int deg[500005], dp[1000000][27], cn = 1,cnt = 1, f[500005], book[500005];
int Find(char *s)
{
int i, pos = 0, len = strlen(s);
for (i = 0; i < len; i++)
{
int k = s[i] - 'a';
if (dp[pos][k] == 0)
return 0;
pos = dp[pos][k];
}
return book[pos];
}
void Insert(char *s)
{
int i, pos = 0, len = strlen(s);
for (i = 0; i < len; i++)
{
int k = s[i] - 'a';
if (dp[pos][k] == 0)
dp[pos][k] = cnt++;
pos = dp[pos][k];
}
book[pos] = cn++;
}
int getf(int u)
{
if (u == f[u])
return u;
else
{
f[u] = getf(f[u]);
return f[u];
}
}
void merge(int u, int v)
{
int t1 = getf(u), t2 = getf(v);
if (t1 != t2)
f[t2] = t1;
}
bool judge()
{
int i, sum = 0;
for (i = 1; i < cn; i++)
{
if (getf(i) != getf(1))
return 0;
if (deg[i] % 2)
sum++;
}
if (sum == 0 || sum == 2)
return 1;
return 0;
}
int main()
{
char s1[15], s2[15];
int i;
for (i = 0; i < 500000; i++)
f[i] = i;
while (~scanf("%s %s", s1, s2))
{
int x = Find(s1);
int y = Find(s2);
if (x == 0)
{
Insert(s1);
x = cn - 1;
}
if (y == 0)
{
Insert(s2);
y = cn - 1;
}
deg[x]++, deg[y]++;
merge(x, y);
}
// for (i = 1; i < cn; i++)
// printf("%d ", getf(i));
if (judge())
printf("Possible\n");
else
printf("Impossible\n");
return 0;
}