您的位置:首页 > 其它

POJ 2513 【字典树】【欧拉回路】

2015-10-07 19:26 435 查看
题意:

有很多棒子,两端有颜色,告诉你两端的颜色,让你把这些棒子拼接起来要求相邻的接点的两个颜色是一样的。

问能否拼接成功。

思路:

将颜色看作节点,将棒子看作边,寻找欧拉通路。

保证图的连通性的时候用到并查集。

这里颜色由于是字符串代替,所以需要用到字典树优化离散化过程。

字典树的学习感谢博客http://www.ahathinking.com/archives/14.html

重点是这个图很棒:



#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<iostream>
#include<stdlib.h>
using namespace std;
int me[250000*2+55];
int out[500005];
struct ti
{
void add(char *,int);
int findi(char *);
ti *mine[26];
int num;
};
void ti::add(char *s,int tmp)
{
int len=strlen(s);
ti *next=this;
for(int i=0;i<len;i++)
{
if(next->mine[s[i]-96]==NULL)
{
next->mine[s[i]-96]=(ti*)malloc(sizeof(ti));
memset(next->mine[s[i]-96]->mine,NULL,sizeof(mine));
next->mine[s[i]-96]->num=0;
}
next=next->mine[s[i]-96];
}
next->num=tmp;
}
int ti::findi(char *s)
{
int len=strlen(s);
ti *next=this;
for(int i=0;i<len;i++)
{
if(next->mine[s[i]-96]==NULL)
{
return 0;
}
next=next->mine[s[i]-96];
}
return next->num;
}
ti tree;
int findme(int n)
{
if(n!=me
)
return me
=findme(me
);
return n;
}
int main()
{
memset(tree.mine,NULL,sizeof(tree.mine));
tree.num=0;
char col1[15],col2[15];
for(int i=1;i<=500050;i++)
{
me[i]=i;
}
int num=0;
while(scanf("%s%s",col1,col2)!=EOF)
{
if(tree.findi(col1)==0)
{
num++;
tree.add(col1,num);
}
if(tree.findi(col2)==0)
{
num++;
tree.add(col2,num);
}
int tmpa=findme(tree.findi(col1));
int tmpb=findme(tree.findi(col2));
if(tmpa!=tmpb)
me[tmpb]=tmpa;
out[tree.findi(col1)]++;
out[tree.findi(col2)]++;
}
int c=0;
int x,y,z;
x=y=z=0;
for(int i=1;i<=num;i++)
{
if(me[i]==i)
c++;
if(out[i]&1)
x++;
}
if(x==1||c>1||x>2)
printf("Impossible\n");
else
printf("Possible\n");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: