POJ 2513 无向欧拉通路+字典树+并查集

时间:2021-05-23 04:08:58

题目大意:

有一堆头尾均有颜色的木条,要让它们拼接在一起,拼接处颜色要保证相同,问是否能够实现

这道题我一开始利用map<string,int>来对颜色进行赋值,好进行后面的并查操作以及欧拉通路的判断,但是map效率太低,超时了

网上看了一遍发现必须得用效率更高的字典树对每个不同的颜色进行赋值

 #include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define N 500020
int fa[N],degree[N],k=;
char str1[],str2[];
struct Node{
int id,cnt;
Node *next[];
Node(){
id=-;
for(int i=;i<;i++) next[i]=NULL;
}
};
Node *root=new Node();
int Insert(char *str){
Node *p=root;
for(int i=;i<strlen(str);i++){
if(p->next[str[i]-'a']==NULL) {Node *q=new Node();p->next[str[i]-'a']=q;}
p=p->next[str[i]-'a'];
}
if(p->id==-) p->id=++k;
return p->id;
}
int find_head(int x)
{
int u=x;
while(x!=fa[x]) x=fa[x];
fa[u]=x;
return x;
}
int Union(int x,int y)
{
int fa_x=find_head(x);
int fa_y=find_head(y);
if(fa_x!=fa_y) fa[fa_x]=fa_y;
return fa_y;
}
int main()
{
int tmp;
for(int i=;i<=;i++) fa[i]=i;
// cout<<in[15]<<' '<<out[20]<<' '<<visit[30]<<endl;
while(scanf("%s",str1)!=EOF){
//if(str1[0]=='0') break;
scanf("%s",str2);
int a=Insert(str1);
int b=Insert(str2);
degree[a]++,degree[b]++;
//cout<<a<<' '<<b<<endl;
tmp=Union(a,b);
}
bool flag=;
for(int i=;i<=k;i++){
if(find_head(i)!=tmp){
flag=false;
break;
}
}
if(!flag) puts("Impossible");
else{
int t=;
for(int i=;i<=k;i++){
if(degree[i]%==) t++;
}
if(t>) puts("Impossible");
else puts("Possible");
}
return ;
}