题目大意:一个小镇有m条街,n个交叉口,每条街上有john的一个朋友,现在john要拜访每个朋友1次,输出字典序最小的访问街道编号。起点是输入第一组数据最小的端点。
题目分析:典型的欧拉回路问题。先判断图是连通的并且所有点度数为偶数,因为这题是无向图,建图的时候每条边正反建一次。由于要字典序最小,所以要先dfs编号较小的街道,所以建图的时候稍微注意一下,我是先把所有的街道排序,先建编号大的边,保证dfs先遍历编号小的街道,从而答案保证字典序最小。详情请见代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 20005;
struct node
{
int from,to,id,next;
bool vis;
}edge[N];
int flag[N];
struct nd
{
int a,b,c;
}lcm[N];
int num;
int x,y;
int set[50];
int degree[50];
int start,ind;
int ans[N],top;
int head[50];
int cmp(struct nd a,struct nd b)
{
if(a.a != b.a)
return a.a < b.a;
else
return a.c > b.c;
}
void init()
{
int i;
for(i = 1;i < 50;i ++)
{
head[i] = -1;
set[i] = i;
degree[i] = 0;
}
memset(flag,0,sizeof(flag));
num = top = 0;
}
int find(int a)
{
int root = a;
while(root != set[root])
root = set[root];
int parent = set[a];
while(parent != root)
{
set[a] = root;
a = parent;
parent = set[a];
}
return root;
}
void join(int a,int b)
{
int root_a = find(a);
int root_b = find(b);
set[root_b] = root_a;
}
int isok()
{
int i;
int cnt = 0;
//for(i = 1;i < 50;i ++)
// printf("%d ",degree[i]);
//printf("\n");
for(i = 1;i < 50;i ++)
{
if(set[i] == i && degree[i])
cnt ++;
if(cnt > 1)
return 0;
if(degree[i] & 1)
return 0;
}
return 1;
}
void build(int s,int e,int idx)
{
edge[num].from = s;
edge[num].to = e;
edge[num].id = idx;
edge[num].vis = 0;
edge[num].next = head[s];
head[s] = num ++;
flag[idx] = 1;
}
void dfs(int u)
{
int i;
for(i = head[u];i != -1;i = edge[i].next)
{
if(flag[edge[i].id])
{
flag[edge[i].id] = 0;
dfs(edge[i].to);
ans[top ++] = edge[i].id;
}
}
}
int main()
{
int i;
int t = 0;
while(scanf("%d%d",&x,&y),(x + y))
{
init();
scanf("%d",&ind);
lcm[0].a = x;
lcm[0].b = y;
lcm[0].c = ind;
lcm[1].a = y;
lcm[1].b = x;
lcm[1].c = ind;
t = 2;
start = x > y?y:x;
//build(x,y,ind);
degree[x] ++;
degree[y] ++;
join(x,y);
while(scanf("%d%d",&x,&y),(x + y))
{
scanf("%d",&ind);
//build(x,y,ind);
degree[x] ++;
degree[y] ++;
join(x,y);
lcm[t].a = x;
lcm[t].b = y;
lcm[t ++].c = ind;
lcm[t].a = y;
lcm[t].b = x;
lcm[t ++].c = ind;
}
sort(lcm,lcm + t,cmp);
for(i = 0;i < t;i ++)
{
build(lcm[i].a,lcm[i].b,lcm[i].c);
//printf("%d %d %d\n",lcm[i].a,lcm[i].b,lcm[i].c);
}
if(isok())
{
dfs(start);
//printf("%d\n",top);
for(i = top - 1;i > 0;i --)
printf("%d ",ans[i]);
printf("%d\n",ans[i]);
}
else
printf("Round trip does not exist.\n");
}
return 0;
}
//372K 63MS