农民 John 每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方.
John 是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个一个栅栏.你必须
编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一
次.John 能从任何一个顶点(即两个栅栏的交点)开始骑马,在任意一个顶点结束.
每一个栅栏连接两个顶点,顶点用1到500标号(虽然有的农场并没有500个顶点).一个顶点上
可连接任意多(>=1)个栅栏.所有栅栏都是连通的(也就是你可以从任意一个栅栏到达另外的所有栅
栏).
你的程序必须输出骑马的路径(用路上依次经过的顶点号码表示).我们如果把输出的路径看成
是一个500进制的数,那么当存在多组解的情况下,输出500进制表示法中最小的一个 (也就是输出
第一个数较小的,如果还有多组解,输出第二个数较小的,等等).
输入数据保证至少有一个解.
PROGRAM NAME: fence
INPUT FORMAT
第 1 行: 一个整数 F(1 <= F <= 1024),表示栅栏的数目
第 2 到 F+1 行: 每行两个整数 i, j(1 <= i,j <= 500)表示这条栅栏连接i与j 号顶点.
SAMPLE INPUT(fence.in)
9
1 2
2 3
3 4
4 2
4 5
2 5
5 6
5 7
4 6
OUTPUT FORMAT
输出应当有 F+1 行,每行一个整数,依次表示路径经过的顶点号.注意数据可能有多组解,但是
只有上面题目要求的那一组解是认为正确的.
SAMPLE OUTPUT(fence.out)
1
2
3 45
4
2
5
4
6
5
7
【分析】:本题是欧拉回路的裸题,直接用求欧拉路径的算法可以过
【代码】:
/* ID:csyzcyj1 PROG:fence LANG:C++ */ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<algorithm> #include<iostream> #include<vector> #include<stack> #include<queue> using namespace std; #define MAX 505 #define MAXN 1026 long long N,max1=0,map[MAX][MAX],degree[MAX]; long long tot=0; long long road[MAXN]; void search(long long now) { for(int i=1;i<=max1;i++) { if(map[now][i]) { map[now][i]--; map[i][now]--; search(i); } } road[++tot]=now; } void euler() { long long s=1; for(int i=1;i<=max1;i++)//找到第一个奇点 { if(degree[i]%2==1) { s=i; break; } } search(s); } int main() { freopen("fence.in","r",stdin); freopen("fence.out","w",stdout); scanf("%lld",&N); for(int i=1;i<=N;i++) { long long A,B; scanf("%lld%lld",&A,&B); map[A][B]++; map[B][A]++; degree[A]++; degree[B]++; max1=max(A,max(B,max1)); } euler(); for(int i=tot;i>=1;i--) printf("%lld\n",road[i]); return 0; }