Description

Farmer John每年有很多栅栏要修理。他总是骑着马穿过每一个栅栏并修复它破损的地方。

John是一个与其他农民一样懒的人。他讨厌骑马,因此从来不两次经过一个栅栏。你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次。John能从任何一个顶点(即两个栅栏的交点)开始骑马,在任意一个顶点结束。

每一个栅栏连接两个顶点,顶点用1到500标号(虽然有的农场并没有500个顶点)。一个顶点上可连接任意多(>=1)个栅栏。两顶点间可能有多个栅栏。所有栅栏都是连通的(也就是你可以从任意一个栅栏到达另外的所有栅栏)。

你的程序必须输出骑马的路径(用路上依次经过的顶点号码表示)。我们如果把输出的路径看成是一个500进制的数,那么当存在多组解的情况下,输出500进制表示法中最小的一个 (也就是输出第一位较小的,如果还有多组解,输出第二位较小的,等等)。

输入数据保证至少有一个解。

Input

第1行: 一个整数F(1 <= F <= 1024),表示栅栏的数目

第2到F+1行: 每行两个整数i, j(1 <= i,j <= 500)表示这条栅栏连接i与j号顶点。

Output

输出应当有F+1行,每行一个整数,依次表示路径经过的顶点号。注意数据可能有多组解,但是只有上面题目要求的那一组解是认为正确的。

Sample Input

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

Sample Output

1
2
3
4
2
5
4
6
5
7

说明

题目翻译来自NOCOW。

USACO Training Section 3.3

题解

欧拉路径的模板题了吧

预备知识:

欧拉回路:从一个点可以遍历整张图,最后回到原来的点

欧拉通路:从一个点可以遍历整张图,最后回不到原来的点

对于无向图而言:(大前提:图联通

欧拉回路:任意点的度数为偶 起点可随意

欧拉通路:有且仅有两个点度数为奇 在遍历时一定要从一个为奇的点到另一个为奇的点

对于有向图:(还是大前提图联通

欧拉回路:每个点入度==出度

欧拉通路:有且仅有一个点出度-入度==1 为起点;有且仅有一个点入度-出度==1 为终点; 其余的点出度==入度

然后这道题的解法和算法学习都借鉴了排名第一的题解Misaka_Azusa的题解

所以是Hierholzers算法啦!

双向存边,记录每个点的度。

从小到大扫一遍  找有没有度数为奇的点 若有则break,从当前点开始dfs(欧拉通路

如果所有点度为偶则从最小的点开始dfs(欧拉回路

 stack<int>st;
void dfs(int x)
{
for(int v=l;v<=r;++v)
if(tu[x][v])
{
tu[x][v]--;
tu[v][x]--;
dfs(v);
}
st.push(x);
return;
}

看代码然后强行理解应该就够了

然后对于stack 一开始自作聪明的成在开头直接输出QAQ

如果有一样的危险想法,讨论区给的这个样例还是蛮助于理解的


以下是全代码

 #include<iostream>
#include<cstdio>
#include<stack>
#include<cmath>
using namespace std;
int du[];
int tu[][];
int l,r;
stack<int>st;
void dfs(int x)
{
for(int v=l;v<=r;++v)
if(tu[x][v])
{
tu[x][v]--;
tu[v][x]--;
dfs(v);
}
st.push(x);
return;
}
int main()
{
int f;
scanf("%d",&f);
l=,r=;
for(int i=;i<=f;++i)
{
int x,y;
scanf("%d%d",&x,&y);
tu[x][y]++;
tu[y][x]++;
du[x]++;
du[y]++;
l=min(l,x);
l=min(l,y);
r=max(r,x);
r=max(r,y);
}
int s=l;
for(int i=l;i<=r;++i)
if(du[i]%==){s=i;break;}
dfs(s);
while(!st.empty())
{
printf("%d\n",st.top());
st.pop();
}
return ;
}

YJQ说这是集训队算法(逃

「USACO」「LuoguP2731」 骑马修栅栏 Riding the Fences(欧拉路径的更多相关文章

  1. 洛谷P2731 骑马修栅栏 Riding the Fences

    P2731 骑马修栅栏 Riding the Fences• o 119通过o 468提交• 题目提供者该用户不存在• 标签USACO• 难度普及+/提高 提交 讨论 题解 最新讨论 • 数据有问题题 ...

  2. 洛谷 P2731 骑马修栅栏 Riding the Fences 解题报告

    P2731 骑马修栅栏 Riding the Fences 题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样 ...

  3. 洛谷 P2731 骑马修栅栏 Riding the Fences

    P2731 骑马修栅栏 Riding the Fences 题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样 ...

  4. P2731 骑马修栅栏 Riding the Fences 题解(欧拉回路)

    题目链接 P2731 骑马修栅栏 Riding the Fences 解题思路 存图+简单\(DFS\). 坑点在于两种不同的输出方式. #include<stdio.h> #define ...

  5. USACO Section 3.3 骑马修栅栏 Riding the Fences

    题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个 ...

  6. P2731 骑马修栅栏 Riding the Fences

    题目描述 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次.John能从任何一个顶 ...

  7. 骑马修栅栏 Riding the Fences

    题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个 ...

  8. LG2731 骑马修栅栏 Riding the Fences

    题意 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次.John能从任何一个顶点( ...

  9. [USACO]骑马修栅栏 Riding the Fences

    题目链接 题目简述:欧拉回路,字典序最小.没什么好说的. 解题思路:插入边的时候,使用multiset来保证遍历出出答案的字典序最小. 算法模板:for(枚举边) 删边(无向图删两次) 遍历到那个点 ...

随机推荐

  1. js Math [ 随机数、绝对值、四舍五入、进一取整、舍去取整、最大值、最小值、圆周率 ]

    <script> /* 数学对象:Math */ with (document) { write('<br>-3.5的绝对值:'+Math.abs(-3.5)); write( ...

  2. Codeforces 713C Sonya and Problem Wihtout a Legend(DP)

    题目链接   Sonya and Problem Wihtout a Legend 题意  给定一个长度为n的序列,你可以对每个元素进行$+1$或$-1$的操作,每次操作代价为$1$. 求把原序列变成 ...

  3. 洛谷P1061 Jam的计数法

    题目描述 Jam是个喜欢标新立异的科学怪人.他不使用阿拉伯数字计数,而是使用小写英文字母计数,他觉得这样做,会使世界更加丰富多彩.在他的计数法中,每个数字的位数都是相同的(使用相同个数的字母),英文字 ...

  4. Codeforces 961 D Pair Of Lines

    题目描述 You are given nn points on Cartesian plane. Every point is a lattice point (i. e. both of its c ...

  5. javafx中多场景的切换

    0.前言 前段时间在做javafx的应用程序,遇到一些坑.以本文记录之.(如有更好的解决办法欢迎评论,本人小白,轻喷) 1.问题 按照官方的中文文档,成功的运行了单一界面的表单登录.于是想自己试试多界 ...

  6. LeetCode第一题以及时间复杂度的计算

    问题描述:给定一组指定整数数组,找出数组中加和等于特定数的两个数. 函数(方法)twoSum返回这两个数的索引,index1必须小于index2. 另外:你可以假设一个数组只有一组解. 一个栗子: I ...

  7. Java的不定参数(eg:Object...)(转)

    第一个例子: public class VariArgs { public static void main(String[] args) { test(); test("aaa" ...

  8. SpringCloud中Rabbitmq的使用

    1.pom配置,添加以来jar包 <dependency> <groupId>org.springframework.cloud</groupId> <art ...

  9. vue2.0 自定义过滤器(filter)实例

    一.过滤器简介 (1)过滤器创建 过滤器的本质 是一个有参数 有返回值的方法 new Vue({ filters:{ myCurrency:function(myInput){ return 处理后的 ...

  10. C++经典面试题解析

    1. // BlankTest.cpp : 定义控制台应用程序的入口点. //题目:将一个文件中的一组整数排序后输出到另一个文件中 #include "stdafx.h" #inc ...