题目描述
John是一个与其他农民一样懒的人。他讨厌骑马,因此从来不两次经过一个栅栏。你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次。John能从任何一个顶点(即两个栅栏的交点)开始骑马,在任意一个顶点结束。
每一个栅栏连接两个顶点,顶点用1到500标号(虽然有的农场并没有500个顶点)。一个顶点上可连接任意多(>=1)个栅栏。两顶点间可能有多个栅栏。所有栅栏都是连通的(也就是你可以从任意一个栅栏到达另外的所有栅栏)。
你的程序必须输出骑马的路径(用路上依次经过的顶点号码表示)。我们如果把输出的路径看成是一个500进制的数,那么当存在多组解的情况下,输出500进制表示法中最小的一个 (也就是输出第一位较小的,如果还有多组解,输出第二位较小的,等等)。
输入数据保证至少有一个解。
输入格式
第1行: 一个整数F(1 <= F <= 1024),表示栅栏的数目
第2到F+1行: 每行两个整数i, j(1 <= i,j <= 500)表示这条栅栏连接i与j号顶点。
输出格式
输出应当有F+1行,每行一个整数,依次表示路径经过的顶点号。注意数据可能有多组解,但是只有上面题目要求的那一组解是认为正确的。
题解:
只需要把模板的mp数组改一改就i行了呀…
AC代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#include<ext/rope>
using namespace std;
using namespace __gnu_cxx;
#define LL long long
const int MAXN = 500+50;
const int MOD = 1e9+7;
const int INF = 1e9;
vector<int> v; int mx,mp[MAXN][MAXN],dag[MAXN];
void dfs(int u){
for(int i=1;i<=mx;i++){
if(mp[u][i]){
mp[u][i]--; mp[i][u]--;
dfs(i);
}
}
v.push_back(u);
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
#endif // ONLINE_JUDGE
int n; scanf("%d",&n);
for(int i=1,u,v;i<=n;i++){
scanf("%d%d",&u,&v);
mp[u][v]++; mp[v][u]++;
dag[u]++; dag[v]++;
mx = max(mx,max(u,v));
}
int st=1;
for(int i=1;i<=mx;i++)
if(dag[i]&1)
{ st=i;break; }
dfs(st);
for(int i=v.size()-1;i>=0;i--) printf("%d\n",v[i]);
return 0;
}