您的位置:首页 > 其它

POJ ~ 2337 ~ Catenyms (欧拉路 + 路径输出)

2018-01-27 12:30 429 查看
题意:给你n个单词(只有小写),要求这些单词首尾相连,问你这n个单词能不能全部连起来,可以连成一条链或者连成一个环,如果可以输出路径,不可以输出“***”。

思路:先判断度数,然后判断图的连通,在回溯的时候记录路径。

虽然AC了但是还是有一个地方不是很明白,看来对递归和回溯的过程理解还是不够啊。

不明白的地方:cnt是全局变量,对于dfs过程,如果过程中选择了错误的路怎么办?为什么却能求出正确答案?哪位大神帮忙解答下,万分感谢!!!比如下面的第三组样例,可以以此为例进行讲解!

AC代码:

//#include <bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int MAXN = 1005;
int n, ans[MAXN], cnt, indegree[30], outdegree[30];
string str[MAXN];
int head[MAXN];
struct Edge
{
int to, Next;
bool flag;
}edge[MAXN];
void init()
{
cnt = 0;
memset(head, -1, sizeof(head));
memset(indegree, 0, sizeof(indegree));
memset(outdegree, 0, sizeof(outdegree));
}
void add_edge(int u, int v, int i)
{
edge[i].flag = false;
edge[i].to = v;
edge[i].Next = head[u];
head[u] = i;
}
void dfs(int u)
{
for (int i = head[u]; i != -1; i = edge[i].Next)
{
if (!edge[i].flag)
{
edge[i].flag = true;
dfs(edge[i].to);
ans[cnt++] = i;
}
}
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
init();
scanf("%d", &n);
for (int i = 0; i < n; i++) cin >> str[i];
sort(str, str + n);
for (int i = n - 1; i >= 0; i--)
{
int u = str[i][0] - 'a', v = str[i][str[i].length()-1]-'a';
outdegree[u]++; indegree[v]++;
add_edge(u, v, i);
}
//度数判断,寻找起点
int cnt1 = 0, cnt2 = 0, start = str[0][0] - 'a';
for (int i = 0; i < 26; i++)
{
if (abs(indegree[i] - outdegree[i]) > 1) cnt1 = 3;
if (indegree[i] - outdegree[i] == -1) start = i, cnt1++;
if (indegree[i] - outdegree[i] == 1) cnt2++;
}
if(!((cnt1 == 0 && cnt2 == 0) || (cnt1 == 1 && cnt2 == 1)))
{
printf("***\n"); continue;
}
//图的连通性
dfs(start);
if (cnt != n)//图不连通
{
printf("***\n"); contin
4000
ue;
}
for (int i = n - 1; i >= 0; i--)
{
cout << str[ans[i]];
if (i != 0) cout << ".";
else cout << endl;
}
}
}
/*
3
6
aloha
arachnid
dog
gopher
rat
tiger
3
oak
maple
elm
5
aa
ab
aba
ba
bb
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: