您的位置:首页 > 其它

poj 1386 欧拉路径

2014-05-07 15:37 393 查看
/*
题意:给出N个单词,一个单词的头字母和另一个单词的尾字母相同则可以相连,问这N个单词是否能完全相连成一行

题解:求欧拉路径
首先以每个单词的首字母和尾字母为点并且连边,然后用DFS求该图是否连通,然后根据点的入度和出度判断是否存在
欧拉路径或者欧拉回路(存在回路也是符合要求的)
*/
#include <cstdio>
#include <cstring>

int map[30][30];
int in[30],out[30];

bool exist[30],vis[30];

void dfs(int u)
{
vis[u] = true;
for(int i=0; i<26; i++)
if (map[u][i] && exist[i] && !vis[i])
dfs(i);
}

int main(void)
{
int t;
scanf("%d",&t);
char str[1005];
while (t--)
{
int n;
scanf("%d",&n);
memset(map,0,sizeof(map));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(exist,false,sizeof(exist));

for(int i=0; i<n; i++)
{
scanf("%s",str);
int len = strlen(str);
int u = str[0]-'a', v = str[len-1]-'a';
map[u][v]++;
in[v] ++;
out[u] ++;
exist[u] = exist[v] = true;
}

// 找出合适的起点进行DFS,入度小于出度的肯定是起点,要么就任意起点
memset(vis,false,sizeof(vis));
int i;
for(i=0; i<26; i++)
if (exist[i])
break;
for(int j=i+1; j<26; j++)
if (exist[j] && in[j] < out[j])
{
i = j;
break;
}
dfs(i);
for(i=0; i<26; i++) // 连通则所有点都遍历了
if (exist[i] && !vis[i])
break;

bool flag = false;
if (i >= 26)
{
int head = 0,tail = 0,mid = 0, sum = 0;
for(int i=0; i<26; i++)
{
if (exist[i])
{
sum++;
if (in[i] == out[i])
mid++;
if (in[i] - out[i] == -1)
head++;
if (in[i] - out[i] == 1)
tail++;
}
}
if (sum == mid || (head == 1 && tail == 1 && mid == sum-2)) // 判断欧拉路径或回路
flag = true;
}

if (flag)
printf("Ordering is possible.\n");
else
printf("The door cannot be opened.\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: