老师方法不懂求问【悬赏关注】
  • 板块P1127 词链
  • 楼主kimi0705
  • 当前回复6
  • 已保存回复6
  • 发布时间2023/1/18 20:11
  • 上次更新2023/10/28 21:16:15
查看原帖
老师方法不懂求问【悬赏关注】
637788
kimi0705楼主2023/1/18 20:11

老师代码

#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 为什么加边是加单词,而统计节点和搜索是字母

2023/1/18 20:11
加载中...