题目链接:Colored Sticks
一道3个知识点结合的题目,可以说单个知识点的题目,都会做,一旦知识点结合起来,题目就不简单了
思路:这个题开始看就知道是并查集,但是不好处理的不同种单词的统计,所以理所应当联想到字典树,上次做字典树的题目啸爷出的是统计相同单词数,这个题目和那个一样,把flag加个编号即可,再利用并查集。
1750ms 水过
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
const int N = 500001;
using namespace std;
int father[N];
int du[N];
char a[20],b[20];
struct node{
int bianhao;
node *next[26];
};
node *root;
int hao;
int findx(int r)
{
while(father[r]!=r)
{
r = father[r];
}
int i = r,j;
while(father[i]!=r)
{
j = father[i];
father[i] = r;
i = j;
}
return r;
}
void merge(int a,int b)
{
int fx = findx(a);
int fy = findx(b);
if(fx != fy)
father[fx]=fy;
}
struct node *make()
{
node *p;
p = (struct node*)malloc(sizeof(struct node));
for(int i = 0;i < 26;i++)
{
p->next[i] = NULL;
}
p->bianhao = 0;
return p;
}
int INsert(char *s)
{
node *p = root;
int n = 0;
int len = strlen(s);
for(int i = 0;i<len;i++)
{
n = s[i]-'a';
if(p->next[n] == NULL)
{
p->next[n] = make();
}
p = p->next[n];
}
if(p->bianhao == 0)
{
hao++;
p->bianhao = hao;
}
return p->bianhao;
}
int ans;
bool flag;
void oula()
{
for(int i = 1;i<=hao;i++)
{
if(du[i]%2==1)
ans++;
}
for(int j=2;j<=hao;j++)
{
if(findx(j)!=findx(1))
{
flag = 1;
break;
}
}
}
void make_root()
{
root=(struct node*)malloc(sizeof(struct node));
for(int i = 0;i<26;i++)
{
root->next[i] = NULL;
}
root->bianhao = 0;
}
int main()
{
hao = 0;
make_root();
for(int i=1;i<=500100;i++)
{
father[i]=i;
}
memset(du,0,sizeof(du));
// int numm = 0;
while(scanf("%s%s",a,b)!=EOF)
{
int u = INsert(a);
int v = INsert(b);
du[u]++;
du[v]++;
merge(u,v);
// numm++;
// if(numm==5)
// break;
}
ans = 0;
oula();
if(( ans == 0|| ans ==2)&& !flag )
printf("Possible\n");
else
printf("Impossible\n");
return 0;
}