由于题目中说数据保证至少有1个解,所以一定存在欧拉路了。选起点的时候如果没有点的度为奇数,那么任何一个点都能做起点。如果有2个奇点,那么就只能也这两个点之一为起点,另一个为终点。但是题目要求输出的是进行进制转换之后最小的(也就是输出第一个数较小的,如果还有多组解,输出第二个数较小的,等等),所以我们要以最小的点做起点。
找出欧拉路的方法就是采用深搜的方式,对于当前的点,把所有点从小到大的搜索,找到和它相连的,找到一个之后删除它们之间的连线,并去搜索新的那个点,如果没有找到点和它相连,那么就把这个点加入输出队列。
不过我们这么操作之后,顺序是反着的,输出时反着输出即可。
注意两点:一、给出点的序号不一定就是从小到大给出的;二、两个点之间可能有不止一条道路。
#include<fstream>
#include<string.h>
using namespace std;
int Min=1<<30,Max=-1;
int map[505][505];
int deg[505];
int path[10000];
int cnt=0;
void dfs(int t)
{
for(int i=Min;i<=Max;i++)
if(map[t][i])
{
map[t][i]--;
map[i][t]--;
dfs(i);
}
path[cnt++]=t;
}
int main()
{
ifstream fin("fence.in");
ofstream fout("fence.out");
int f,u,v;
fin>>f;
memset(map,0,sizeof(map));
memset(deg,0,sizeof(deg));
for(int i=0;i<f;i++)
{
fin>>u>>v;
if(Min>u)
Min=u;
if(Max<u)
Max=u;
if(Min>v)
Min=v;
if(Max<v)
Max=v;
map[u][v]++;
map[v][u]++;
deg[u]++;
deg[v]++;
}
int i;
for(i=Min;i<=Max;i++)
if(deg[i]%2)
{
u=i;
break;
}
if(i>Max)
u=Min;
dfs(u);
for(i=cnt-1;i>=0;i--)
fout<<path[i]<<endl;
return 0;
}