UVA302 John's trip

John有很多朋友住在不同的街,想去拜访每位朋友,同时希望走的路最短。因为道路很窄,John在一条路上不能往回走。

John希望从家出发,拜访完所有的朋友之后回到自己的家,且总路程最短。John意识到如果可以每条路径都走一次,然后返回起点,应该是最短的路径。写一个程序帮助John找到这样的路径。

给出的每条街连接两个路口,最多有1995条街(编号从1到n),44个路口(编号从1到m)。

裸的欧拉回路题,可以不用(dfs)

我们用两个栈,一个用来模拟,一个用来记答案。因为答案要求保证字典序最小的那一组,所以我们先对与每个点相连的点按从小到大排序,这样先选编号小的点,就可以保证找到的第一组答案就是字典序最小的那一组答案了。

小优化:当我们访问完一条边后,把当前选的这个点连的边删除,这样就可以保证每次访问的边都是未访问过的边了,时间复杂度也由(O(N×M))降为了(O(N+M))

还有最要注意的一点就是每一组解行末无空格。(被卡了好久= =)

Code

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
struct edge
{
	int to,id;
}stk[10000];
int st,d[50],n,ans[10000],num,top,vis[10000],m;  //d存每个点的度,如果有度数是奇数的点,那么肯定无欧拉回路.
vector <edge> a[50];
int cmp(edge x,edge y)
{
	return x.id<y.id;
}
void euler(int s)       //找欧拉回路
{
	stk[++top].to=s;    //模拟栈
	vector <edge>::iterator it;
	while (top>0)
	{
		int u=stk[top].to,w=stk[top].id,fl=0;
		for (it=a[u].begin();it!=a[u].end();it++)
		{
			int v=(*it).to,i=(*it).id;
			if (!vis[i])     //vis代替删边
			{
				fl=1;
				stk[++top].to=v;
				stk[top].id=i;
				vis[i]=1; 
				break;       //进入下一层
			}
		}
		if (!fl)        //回溯
		{
			top--;
			ans[++num]=w;    //更新答案栈
		}
	}
}
void clear()
{
	for (int i=1;i<=n;i++)
		a[i].clear(),d[i]=0,vis[i]=0;
	for (int i=1;i<=1995;i++)
		vis[i]=0;
	num=0;
	m=0;
}
int main()
{
	int x,y,z;
	cin>>x>>y;
	while (x||y)
	{
		clear();
		int fl=0;
		cin>>z;
		n=max(x,y);
		st=min(x,y);
		m++;
		a[x].push_back((edge){y,z});
		a[y].push_back((edge){x,z});
		d[x]++;
		d[y]++;
		cin>>x>>y;
		while (x||y)
		{
			cin>>z;
			a[x].push_back((edge){y,z});
			a[y].push_back((edge){x,z});
			n=max(max(x,y),n);
			d[x]++;
			d[y]++;
			m++;
			cin>>x>>y;
		}
		for (int i=1;i<=n;i++)
			if (d[i]%2!=0)
			{
				cout<<"Round trip does not exist."<<endl;
				fl=1;
				break;
			}
		if (!fl)
		{
			for (int i=1;i<=n;i++)
				sort(a[i].begin(),a[i].end(),cmp);//排序保证解的字典序最小
			euler(st);
			for (int i=num-1;i>=2;i--)
				cout<<ans[i]<<" ";
			cout<<ans[1]<<endl;
		}
		cin>>x>>y;
		cout<<endl;
	}
	return 0;
}
原文地址:https://www.cnblogs.com/sdlang/p/13068110.html