Accept: 30 Submit: 68
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
Sample Output
Source
FOJ有奖月赛-2016年4月(校赛热身赛)思路:通过题意我们可以知道在输入数据中值只出现一次的便是起点或者终点(肯定只有两个点,因为该题的路径就是一条链),因为输出的是字典序最小的所以那两个点中值小的为起点而值相对大的为终点,但1 <= ui, vi <= 1e9,不能开那么大的数组,用STL中的map来离散化就可以了。找到起点和终点后,用STL中的set来二分通过当前路径的终点去查找起点,并打印路径。做了这题后,顿时感觉STL的强大。。Orz
代码:
#include <cstdio>
#include <cstring>
#include <utility>
#include <map>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
typedef long long ll;
#define maxn (int)1e5
pair<int,int>point[maxn];
set<pair<int,int> >s1;
map<int,int>mp1,mp2,mp3;
int main()
{
#ifdef CDZSC_June
freopen("t.txt","r",stdin);
#endif // CDZSC_June
int n,p;
while(~scanf("%d",&n))
{
mp1.clear();mp2.clear();
s1.clear();mp3.clear();
p = 1;
for(int i = 0; i<n; i++)
{
scanf("%d%d",&point[i].first,&point[i].second);
s1.insert(point[i]);
s1.insert(make_pair(point[i].second, point[i].first));//因为路径的双向的
if(mp1[point[i].first] == NULL){
mp1[point[i].first] = p;
mp2[p] =point[i].first;
mp3[p] = 1;
p++;
}
else{
mp3[mp1[point[i].first]]++;
}
if(mp1[point[i].second] == NULL){
mp1[point[i].second] = p;
mp2[p] =point[i].second;
mp3[p] = 1;
p++;
}
else{
mp3[mp1[point[i].second]]++;
}
}
int s = -1,t = -1;
for(int i = 0 ;i<p; i++){//只出现一次的为起点或终点
if(mp3[i] == 1 ){
if(s == -1){
s = mp2[i];
}
else{
t = mp2[i];
}
}
}
if(s > t) swap(s,t);//使小的为起点,大的为终点
printf("%d",s);
set<pair<int,int> >::iterator it,itt,temp,itt1;
it = s1.lower_bound(make_pair(s,0));
while(s1.size() > 2)
{
itt = s1.lower_bound(make_pair(it->second,0));
itt1 = s1.lower_bound(make_pair(it->second,it->first));
s = itt->first;
temp = it;
if(s1.size() > 2){
printf(" %d",s);
}
s1.erase(temp);
s1.erase(itt1);
it = s1.lower_bound(make_pair(s,0));
}
printf(" %d\n",t);
}
return 0;
}