题意:给定一张图,每个点是一种颜色,用一个单词表示,问是否存在欧拉通路。
分析:欧拉路径问题,求是否有欧拉通路
1.定理:无向图G有欧拉通路的充分必要条件是G为连通图,并且G仅有两个奇度结点或者无奇度结点。
(1)当G是仅有两个奇度结点的连通图时,G的欧拉通路必以此两个结点为端点。
(2)当G是无奇度结点的连通图时,G必有欧拉回路。
2.一个有向图D具有欧拉通路,当且仅当D是连通的,且除了两个顶点外,其余顶点的入度均等于出度,这两个特殊的顶点中,一个顶点的入度比出度大1,另一个顶点的入度比出度小1. 推论:一个有向图D是欧拉图(具有欧拉回路),当且仅当D是连通的,且所有顶点的出度等于入度。
3.trie树是一种存储名称的普遍方法。
解法:并查集判断是否连通,用trie存储每种颜色。看度是否符合要求。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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;
}
#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;
}