John‘s trip(欧拉图)

约翰的旅行
时间限制: 1000MS 内存限制: 65536K
提交总数: 12292 接受: 4239 特别法官
描述

小约翰尼有一辆新车。他决定开车在城里转转去看望他的朋友。约翰尼想去拜访他所有的朋友,但是有很多朋友。在每条街上他都有一个朋友。他开始思考如何尽可能缩短他的行程。很快,他意识到最好的办法就是只穿过镇上的每条街道一次。当然,他想在父母家开始的同一个地方完成他的旅行。
约翰尼镇的街道被整数命名为1995年<1到
n。交汇点由 1 至 m、m <= 44 的整数独立命名。没有路口连接超过44条街道。镇上所有的路口都有不同的数字。每条街正好连接两个路口。镇上没有两条街道有相同的数字。他立即开始计划他的往返行程。如果有不止一次这样的往返旅行,他会选择一个,当写下来作为街道号码序列是词汇学上最小的。但约翰尼连一次这样的往返都找不到。
帮助约翰尼,并写一个程序,找到所需的最短的往返
行程。如果往返不存在,程序应写一条消息。假设约翰尼住在街道结尾的路口, 首先出现在输入中, 数量较小。镇上所有的街道都是双向的。镇上每条街都有一条路要走另一条街。镇上的街道很窄,一旦他在街上,就不可能把车倒回去
输入

输入文件由几个块组成。每个街区描述一个城镇。块中的每个行包含三个整数 x:y;z,其中x>0和y>0是街道编号z连接的路口数。块的末端由包含 x = y = 0 的行标记。输入文件的末尾有一个空块,x =y = 0。
输出

输出每个块的一行包含街道编号的序列(序列的单个成员按空间分开),描述约翰尼的往返旅程。如果找不到往返,相应的输出块包含"往返不存在"的消息。
示例输入

1 2 1
2 3 2
3 1 6
1 2 5
2 3 3
3 1 4
0 0
1 2 1
2 3 2
1 3 3
2 4 4
0 0
0 0
样本输出

1 2 3 5 4 6
Round trip does not exist.

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
typedef long long  ll;
int minn,maxn;
int deg[100];   //deg 存储顶点的度数 
int vis[2000],s[2000];  //dis来判断道路是否已经走过  s用来记录路的顺序 
int stop;   //stop记录边数 
#define ccc ios::sync_with_stdio(false);
struct node{
	int L,R;
}R[2000];
bool check()	//检验顶点度数是否均为偶数(检验其是否为欧拉图) 
{
	for(int i=1;i<=50;i++)
		if(deg[i]%2==1) return false;
	return true;
}
void dfs(int a)
{
	for(int i=1;i<=maxn;i++)
	{
		if(!vis[i]&&(R[i].L==a||R[i].R==a))
		{
			vis[i]=1;
		
			dfs(R[i].L+R[i].R-a);
			s[stop++]=i;
		}
	}
}
int main()
{
	ccc;
	int x,y,z;
	while(cin>>x>>y,x>0)
	{
		memset(deg,0,sizeof(deg));
		minn=min(x,y);				//minn记录john家编号 
		cin>>z;
		maxn=z;
		R[z].L=x,R[z].R=y;
		deg[x]++,deg[y]++;
		while(cin>>x>>y,x>0)
		{
			cin>>z;
			maxn=max(maxn,z);
			R[z].L=x,R[z].R=y;
			minn=min(minn,min(x,y));
			deg[x]++,deg[y]++; 
		}
		if(check())
		{
			memset(vis,0,sizeof(vis));
			stop=0;
			dfs(minn);
			for(int i=stop-1;i>=1;i--) cout<<s[i]<<" ";
			cout<<s[0]<<endl;
		}
		else cout<<"Round trip does not exist."<<endl;
		
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值