2392 - 骑马修栅栏

通过次数

0

提交次数

0

时间限制 : 1 秒 内存限制 : 128 MB

农民John每年有很多栅栏要修理。他总是骑着马穿过每一个栅栏并修复它破损的地方。 
  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行,每行一个整数,依次表示路径经过的顶点号。注意数据可能有多组解,但是只有上面题目要求的那一组解是认为正确的。

输入/输出样例

输入格式

9
1 2
2 3
3 4
4 2
4 5
2 5
5 6
5 7
4 6

输出格式

1
2
3
4
2
5
4
6
5
7

C语言解答

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int G[510][510];
int n, f;
int path[2000];
int degree[510];
int index;

void dfs(int u){
for(int v = 1;v <= n; v++){
    if(G[u][v]){
        G[u][v]--;
        G[v][u]--;
        dfs(v);
    }
}
path[index++] = u;
}

int main()
{
    while(scanf("%d",&f) != EOF){
        memset(G,0,sizeof(G));
        memset(path,0,sizeof(path));
        memset(degree,0,sizeof(degree));
        n = 0;
        for(int i = 0;i < f; i++){
            int a, b;
            scanf("%d%d",&a,&b);
            G[a][b]++;
            G[b][a]++;
            degree[a]++;
            degree[b]++;
            int temp = a < b ? b : a;
            n = n < temp ? temp : n;
        }
        int st = 1;
        for(int i = 1;i <= n; i++){
            if((degree[i] & 1) == 1){
                st = i;
                break;
            }
        }
        index = 0;
        dfs(st);
        for(int i = index-1;i>=0;i--){
            printf("%d\n",path[i]);
        }
    }
    return 0;
}

C++解答

#include<iostream> 
#define MAX 1024
using namespace std;
int g[MAX][MAX]={0};
int d[MAX]={0};
int r[MAX]={0};
int n=0,e,a,b,m=0;
void in();
void find(int i);
void out();
int main()
{
	in();
	for(int i=1;i<n+1;i++)
	{
		if(d[i]%2==1)
		{
			find(i);
			out();
			return 0;
		}
	}
	find(1);
	out();
	return 0;
}
void in() {
	cin>>e;
	for(int i=1;i<e+1;i++)
	{
		cin>>a>>b;
		m=max(a,b);
		n=max(n,m);
		g[a][b]++;
		g[b][a]++;
		d[a]++;
		d[b]++;
	}
}
void find(int i) {
	for(int j=1;j<n+1;j++)
	{
		if(g[i][j]>0)
		{
			g[i][j]--;
			g[j][i]--;
			find(j);
		}
	}
	r[++r[0]]=i;
}
void out() {
	for(int i=r[0];i>0;i--)
	{
		cout<<r[i]<<endl;
	}
}