poj2513

题意:给定一张图,每个点是一种颜色,用一个单词表示,问是否存在欧拉通路。

分析:欧拉路径问题,求是否有欧拉通路

1.定理:无向图G有欧拉通路的充分必要条件是G为连通图,并且G仅有两个奇度结点或者无奇度结点。
(1)当G是仅有两个奇度结点的连通图时,G的欧拉通路必以此两个结点为端点。
(2)当G是无奇度结点的连通图时,G必有欧拉回路。

2.一个有向图D具有欧拉通路,当且仅当D是连通的,且除了两个顶点外,其余顶点的入度均等于出度,这两个特殊的顶点中,一个顶点的入度比出度大1,另一个顶点的入度比出度小1. 推论:一个有向图D是欧拉图(具有欧拉回路),当且仅当D是连通的,且所有顶点的出度等于入度。

3.trie树是一种存储名称的普遍方法。

解法:并查集判断是否连通,用trie存储每种颜色。看度是否符合要求。

View Code
#include <iostream>
#include
<cstdio>
#include
<cstdlib>
#include
<cstring>
usingnamespace std;

#define L 100
#define maxn 500050

struct Node
{
Node
*next[26];
int x, id;
bool end;
}trie[
550000], *color[maxn];

int ncount =0, colornum =0, father[maxn];

int getanc(int a)
{
if (father[a] == a)
return a;
return father[a] = getanc(father[a]);
}

void merge(int a, int b)
{
father[getanc(a)]
= getanc(b);
}

Node
*ins(Node *proot, char*word)
{
if (word[0] =='\0')
{
if (!proot->end)
{
proot
->end =true;
proot
->id = colornum;
color[colornum
++] = proot;
father[proot
->id] = proot->id;
}
proot
->x++;
return proot;
}
int index = word[0] -'a';
if (!proot->next[index])
{
ncount
++;
proot
->next[index] = trie + ncount;
}
return ins(proot->next[index], word +1);
}

int main()
{
// freopen("t.txt", "r", stdin);
memset(trie, 0, sizeof(trie));
char st[L];
while (gets(st) && strcmp(st, "") !=0)
{
char*word1 = strtok(st, "");
char*word2 = strtok(NULL, "");
Node
*a = ins(trie, word1);
Node
*b = ins(trie, word2);
merge(a
->id, b->id);
}
int temp =0;
for (int i =0; i < colornum; i++)
if (father[i] == i)
temp
++;
if (temp >1)
{
printf(
"Impossible\n");
return0;
}
temp
=0;
for (int i =0; i < colornum; i++)
if (color[i]->x &1)
temp
++;
if (temp ==2|| temp ==0)
printf(
"Possible\n");
else
printf(
"Impossible\n");

return0;
}
posted @ 2011-05-17 14:05  undefined2024  阅读(1090)  评论(0)    收藏  举报