Problem 2227 邮票
Accept: 52 Submit: 152
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
一天Bob收到一封信。Bob知道瓦罗兰大陆的邮局从A城市送信到B城市,乐意使用从A城市到B城市的邮票(A, B),或者使用从B城市到A城市的邮票(A, B),但是由于瓦罗兰大陆的城市繁多,所以并不是所有城市之间都能直接发送接收信件,换句话说,某两个城市想要通行邮件必须经过其他城市才行,但是邮局发送一次邮件的路途中从不会通过一座城市两次。
现在在Bob的信封上有N个邮票,Bob想知道这封信件是如何周转到达他手中的。
Input
题目有多组数据。
每组数据第一行包含一个整数,N ( 2 <= N <= 1e5),代表信件上的N封邮票。
接下有N行数据。第 i 行数据包含两个整数 ui,vi,代表从城市ui发送到城市vi的邮票,ui代表城市的编号,每个城市的编号互不相同,(ui != vi ,1 <= ui, vi <= 1e9)。
输入数据保证有解。
Output
每组样例的结果输出为一行, 每行包括N+1个被空格隔开的整数,代表着信件依次经过的城市编号。
若有多组可行答案,输出字典序最小的那组答案。
Sample Input
2
1 100
100 2
3
3 1
100 2
3 2
Sample Output
1 100 2
1 3 2 100
Source
FOJ有奖月赛-2016年4月(校赛热身赛)
对于无向图的欧拉路径 :起点终点的度为1,其间道路上的点的度都为2.
对于输出按照最小字典序输出:因为起点和终点的编号不可能相同,所以比对一下度为1的点哪个节点编号比较小,我们从这个节点开始Dfs找一条欧拉路径即可。
AC代码:
#include<stdio.h>
#include<string.h>
#include<map>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
vector<int >a[1000005];
int degree[100005];
int ans[100005];
int vis[100005];
int tt;
void Dfs(int u)
{
vis[u]=1;
ans[tt++]=u;
for(int i=0;i<a[u].size();i++)
{
int v=a[u][i];
if(vis[v]==0)Dfs(v);
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
tt=0;
map<int ,int >mp;
map<int ,int>fmp;
for(int i=1;i<=n+1;i++)a[i].clear();
memset(vis,0,sizeof(vis));
memset(ans,-1,sizeof(ans));
memset(degree,0,sizeof(degree));
int cont=1;
for(int i=0;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
if(mp[x]==0)
{
fmp[cont]=x;
mp[x]=cont++;
}
if(mp[y]==0)
{
fmp[cont]=y;
mp[y]=cont++;
}
a[mp[x]].push_back(mp[y]);
a[mp[y]].push_back(mp[x]);
degree[mp[x]]++;
degree[mp[y]]++;
}
for(int i=1;i<cont;i++)
{
if(degree[i]==1)
{
memset(vis,0,sizeof(vis));
Dfs(i);
break;
}
}
for(int i=0;i<tt;i++)
{
ans[i]=fmp[ans[i]];
}
int flag=0;
if(ans[0]>ans[tt-1])reverse(ans,ans+tt);
for(int i=0;i<tt;i++)
{
if(i==0)printf("%d",ans[i]);
else printf(" %d",ans[i]);
}
printf("\n");
}
}