John’s trip
题意
Johnny拥有了一辆新车,他准备驾车在城里拜访他的朋友们。Johnny要去拜访他所有的朋友。他有许多朋友,每一条街道上就有一个朋友。他就开始考虑如何使得他的路程尽可能短,不久他就发现经过城里的每条街道一次且仅仅一次是最好的方法。当然,他要求路程的结束和开始是在同一地点,他父母的家。
在Johnny所在的城里,街道用从1到n的整数来标识,n<1995。街道口用从1到m的整数来标识,m≤44。城镇中所有的路口有不同的编号。每条街道仅连接两个路口。在城中所有街道有唯一的编号。Johnny要开始计划他的环城之行。如果存在两条以上的环线,他就选择按字典序最小的街道编号序列输出。
但Johnny无法找到甚至一条的环线。请您帮助Johnny写一个程序,来找到所要求的环线;如果环线不存在,程序要给出有关信息。设定Johnny生活在最小编号的第1街的路口,在城里所有的街道是双向的,并且从每一条街道都有到另一条街道的路,街道很窄,当汽车进入一条街道以后,不可能调头。
输入
输入包含若干测试用例,每个测试用例描述一座城。在一个测试用例中每一行给出3个整数x, y, z,其中x>0,y>0是连接街道编号为z的两个路口的编号。每个测试用例以x = y = 0的一行为结束。输入以一个空测试用例x=y=0为结束。
输出
相应于输入中的每个测试用例,输出两行。第一行给出一个街道编号序列(序列中每个成员之间用空格分开),以表示Johnny所走的闭链。如果找不到闭链,则输出“Round trip does not exist.”。第二行为空行。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=3000;
//记录路径
int ans[maxn];
int vis[maxn];
int in[maxn];
int sum=0,n=0;
struct node{
int l,r;
}a[maxn];
//判断是否有欧拉回路
int judge()
{
for(int i=1;i<=n;i++)
if(in[i]%2!=0)
return 0;
return 1;
}
//寻找欧拉回路
void search(int u)
{
for(int i=1;i<=n;i++)
if((a[i].l==u||a[i].r==u)&&!vis[i])
{
vis[i]=1;
search(a[i].l+a[i].r-u);
ans[sum++]=i;
}
}
int main()
{
int x,y,z;
while(scanf("%d%d",&x,&y),x+y)
{
sum=0,n=0;
memset(vis,0,sizeof(vis));
memset(in,0,sizeof(in));
scanf("%d",&z);
a[z].l=x;in[x]++;
a[z].r=y;in[y]++;
n=max(n,z);
while(scanf("%d%d",&x,&y),x+y)
{
scanf("%d",&z);
a[z].l=x;in[x]++;
a[z].r=y;in[y]++;
n=max(n,z);
}
if(!judge())
printf("Round trip does not exist.\n");
else{
search(1);
for(int i=n-1;i>=0;i--)
if(i!=0)
printf("%d ",ans[i]);
else
printf("%d\n",ans[i]);
}
}
return 0;
}