John's trip(欧拉回路:输出回路)

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值