USACOTraining 3.3.1 Riding the Fences 骑马修栅栏 题解

    农民 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;
}


 

转载注明出处: http://blog.csdn.net/u011400953

你可能感兴趣的:(USACOTraining 3.3.1 Riding the Fences 骑马修栅栏 题解)