裸欧拉路,至于字典序就用连接表的时候按街道大小从小到大存边即可。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int vis[2005],in[2005],it[45];
int a[2005],cnt,b[2005],tot;
struct pi{
int to;
int id;
}pp;
vector<pi >g[2005];
int pa[45];
int find(int p){
if(pa[p]==p) return p;
return pa[p]=find(pa[p]);
}
void merg(int a,int b){
int x,y;
x=find(a);
y=find(b);
pa[x]=y;
}
int cmp(pi a,pi b){
return a.id<b.id;
}
void dfs(int u){
int m,p;
p=g[u].size();
while(it[u]<p){
int m=it[u];
it[u]++;
if(vis[g[u][m].id]) continue;
vis[g[u][m].id]=1;
dfs(g[u][m].to);
a[cnt++]=g[u][m].id;
}
}
void get(int cnt){
int i,j;
i=cnt-1;
j=cnt-1;
while(i>=0&&j>=0){
if(a[i]==b[j]){
i--;
j--;
continue;
}
if(a[i]<b[j]){
for(i=cnt-1;i>=0;i--) b[i]=a[i];
return ;
}
else return ;
}
}
int main()
{
int i,j,n;
while(1){
n=0;
for(i=1;i<=2000;i++) g[i].clear();
memset(vis,0,sizeof(vis));
memset(in,0,sizeof(in));
for(i=1;i<=44;i++) pa[i]=i;
cnt=0;
while(1){
int a,b,c;
scanf("%d%d",&a,&b);
if(a==0&&b==0){
break;
}
in[a]++;
in[b]++;
merg(a,b);
scanf("%d",&c);
pp.to=b;
pp.id=c;
g[a].push_back(pp);
pp.to=a;
g[b].push_back(pp);
n++;
}
if(n==0) break;
int f=0;
for(i=1;i<=44;i++){
if(in[i]%2==1){
f=1;
break;
}
}
if(f){
printf("Round trip does not exist.\n");
continue;
}
int x=-1;
for(i=1;i<=44;i++){
if(in[i]>0){
if(x==-1) x=find(i);
else{
if(find(i)!=x){
f=1;
break;
}
}
}
}
if(f){
printf("Round trip does not exist.\n");
continue;
}
x=0;
for(i=1;i<=44;i++){
if(in[i]>0){
sort(g[i].begin(),g[i].end(),cmp);
}
}
for(i=1;i<=44;i++){
if(in[i]>0){
memset(vis,0,sizeof(vis));
cnt=0;
memset(it,0,sizeof(it));
dfs(i);
if(x==0){
tot=cnt;
for(j=0;j<cnt;j++) b[j]=a[j];
x=1;
}
else{
get(cnt);
}
}
}
for(i=cnt-1;i>=0;i--){
if(i!=cnt-1) printf(" ");
printf("%d",b[i]);
}
printf("\n");
}
}