本题有两个要求,一是求欧拉回路,二是保证路径字典序最小
联通图有欧拉回路的充要条件是每个点的度都是偶数
从起点开始DFS,顺序保存DFS路径(在递归中用栈),把每一段连续走的DFS路径看成独立的部分,如果走到一个位置不能走了,而且还有其他边没有遍历,那么就说明这个部分应该在其他未遍历的部分后走,所以DFS回溯到之前的结点后,再走另一条支路,这一段的路径应该在之前那段路径的前面。这些用栈就可以自动实现。
代码:
#include <cstdio>
#include <cstring>
#include <stack>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#include <stack>
bool vis[2000];
int G[50][2000];
stack <int> res;
int in[50];
int N,M;
void euler(int n){
for(int i=0;i<=M;i++){
if(!G[n][i]||vis[i]) continue;
vis[i]=1;
euler(G[n][i]);
res.push(i);
}
}
int main(){
int s,t;
while(~scanf("%d%d",&s,&t)){
if(!s&&!t) break;
while(!res.empty()) res.pop();
memset(vis,0,sizeof(vis));
memset(in,0,sizeof(in));
memset(G,0,sizeof(G));
int sta=min(s,t);
int id;
N=max(s,t);
scanf("%d",&id);
M=id;
G[s][id]=t;
G[t][id]=s;
in[s]++; in[t]++;
while(1){
scanf("%d%d",&s,&t);
if(!s&&!t) break;
scanf("%d",&id);
G[s][id]=t;
G[t][id]=s;
in[s]++; in[t]++;
M=max(id,M);
N=max(s,N);
N=max(t,N);
}
bool flag=0;
for(int i=1;i<=N;i++){
if(in[i]&1){
printf("Round trip does not exist.\n");
flag=1;
break;
}
}
if(flag) continue;
euler(sta);
printf("%d",res.top());
res.pop();
while(!res.empty()){
printf(" %d",res.top());
res.pop();
}
printf("\n");
}
return 0;
}