老师代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010;
int n, len[maxn], ans[maxn], deg[30], cnt, top;
int head[maxn], en;
bool flag, vis[maxn];
string s[maxn];
struct edge {
int to, nxt;
} e[maxn*maxn];
void dfs ( int u ) {
if ( flag )
return ;
ans[top++] = u;
vis[u] = true;
int v;
for ( int i=head[u]; ~i; i=e[i].nxt ) {
v = e[i].to;
if ( !vis[v] )
dfs ( v );
}
if ( top == n ) //如果链上了所有点,说明成功了
flag = true;
else {
vis[u] = false;
top--;
}
}
void addedge ( int u, int v ) { //链式前向星
e[cnt].to = v;
e[cnt].nxt = head[u];
head[u] = cnt++;
}
int main() {
cin >> n;
for ( int i=1; i<=n; i++ )
cin >> s[i];
sort ( s+1, s+n+1 );
for ( int i=1; i<=n; i++ )
len[i] = s[i].size();
memset ( head, -1, sizeof ( head ) );
for ( int i=1; i<=n; i++ )
for ( int j=n; j>=1; j-- ) //j从大到小的目的是是的字典序小的单词能先被遍历到,因为链式前向星是“后进先出”
if ( i!=j && s[i][len[i]-1]==s[j][0] ) //i单词的尾和j单词的头相同并且两个单词不是同一个
addedge ( i, j ); //加边
for ( int i=1; i<=n; i++ ) {
deg[s[i][0]-'a']++;
deg[s[i][len[i]-1]-'a']--;
}
int k = 0, start; //变量k统计符合条件的起点的数目,若为欧拉路则k为1,欧拉回路则k为0,其他情况输出不存在
for ( int i=0; i<26; i++ ) {
if ( deg[i] == 1 ) {
k++;
start = i;
}
if ( deg[i] == 2 )
k = 2;
if ( k == 2 )
break;
}
if ( k == 2 ) //说明有多个起点
cout << "***" << endl;
else if ( k == 1 ) {
for ( int i=1; i<=n; i++ )
if ( s[i][0]-'a' == start )
dfs ( i );
} else //形成的是欧拉回路,我们从小到大遍历每个点做起点的情况
for ( int i=1; i<=n; i++ )
dfs ( i );
if ( !flag )
cout << "***" << endl;
else {
for ( int i=0; i < top-1; i++ )
cout << s[ans[i]] << '.';
cout << s[ans[top-1]] << endl;
}
return 0;
}
疑问:
for ( int i=0; i<26; i++ ) {
if ( deg[i] == 1 ) {
k++;
start = i;
}
if ( deg[i] == 2 )//????
k = 2;//??
if ( k == 2 )//??
break;//??
}
为什么deg【i】==2
为什么加边是加单词,而统计节点和搜索是字母