约翰的旅行
时间限制: 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;
}