P2731 骑马修栅栏 Riding the Fences

题目背景

Farmer 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行,每行一个整数,依次表示路径经过的顶点号。注意数据可能有多组解,但是只有上面题目要求的那一组解是认为正确的。


好气啊,我觉得这个欧拉路求法及其难以接受。。

欧拉路:从一个点出发,遍历每一个边刚好一次,到达任意一个点的路径称为欧拉路。

若起点和终点不相等,则起点和终点的度数为奇数;

若起点和终点相等,则称之为欧拉回路,整个无向连通图的每个点的度数都为偶数。

求法:从一个合法的起点产生一颗搜索树,对除起点和终点的(在欧拉回路中我们假装把它们分开考虑)每一个点都可以从一个最早的边进入,然后从一个最晚的边出去,我们忽略这两条边,对这个点就产生了一个递归的子问题,相当于从这个点产生了一个子搜索树。

当搜索树产生的点到达搜索树的起点的时候,我们不对这条路径进行存储,因为路径上的某些点可能产生的搜索树可能因为遍历顺序的问题还没有被扩展,而是当回退的时候,我们就用栈存储这条路径,这就保证了回退路径上所有的点都已经对自己的搜索树进行了扩展。对于每一颗搜索树的出边和入边两两进行配对,倒序着形成了一个个环。

倒着存储的核心,确保路径上每一点自己的子问题已经解决

为了保证复杂度,我们用前向星遍历边之后,得将head数组向后置,以便减少不必要的遍历。同时,也要判断每条边是否被遍历,因为是双向边。

对于此题,如果要保证字典序,则每个点优先遍历合法的最小的点,这样小的点就后进栈,当倒序输出栈的时候,自然也就是最小字典序了。


Code:

#include <cstdio>
#include <iostream>
const int N=502;
const int M=2050;
int g[N][N],head[N],Next[M],to[M],cnt=1,S=N,m,in[N];
void add(int u,int v)
{
Next[++cnt]=head[u];to[cnt]=v;head[u]=cnt;
}
void init()
{
scanf("%d",&m);
int u,v;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
if(u>v) std::swap(u,v);
g[u][v]++;
in[v]++,in[u]++;
S=S<u?S:u;
}
for(int i=500;i;i--)
if(in[i]&1)
S=i;
for(int i=500;i;i--)
for(int j=500;j;j--)
{
while(g[i][j]--)
add(i,j),add(j,i);
}
}
int s[M],tot,vis[M];
void dfs(int now)
{
for(int i=head[now];i;i=Next[i])
{
if(!vis[i])
{
vis[i]=1;
vis[i^1]=1;
head[now]=Next[i];
dfs(to[i]);
}
}
s[++tot]=now;
}
void work()
{
dfs(S);
for(int i=tot;i;i--)
printf("%d\n",s[i]);
}
int main()
{
init();
work();
return 0;
}

2018.7.4

洛谷 P2731 骑马修栅栏 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 解题思路 存图+简单\(DFS\). 坑点在于两种不同的输出方式. #include<stdio.h> #define ...

  4. 洛谷P2731 骑马修栅栏 [欧拉回路]

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

  5. 洛谷P2731骑马修栅栏

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

  6. P2731 骑马修栅栏 Riding the Fences

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

  7. luogu P2731 骑马修栅栏 Riding the Fences

    入度为奇数的点,搜他. 最好邻接矩阵... #include<cstdio> #include<iostream> #define R register int using n ...

  8. 欧拉回路--P2731 骑马修栅栏 Riding the Fences

    实在懒得复制题干了 *传送 1.定义 *如果图G(有向图或者无向图)中所有边一次仅且一次行遍所有顶点的通路称作欧拉通路. *如果图G中所有边一次仅且一次行遍所有顶点的回路称作欧拉回路. *具有欧拉回路 ...

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

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

随机推荐

  1. Netty源码分析第2章(NioEventLoop)---->第2节: NioEventLoopGroup之NioEventLoop的创建

    Netty源码分析第二章: NioEventLoop   第二节: NioEventLoopGroup之NioEventLoop的创建 回到上一小节的MultithreadEventExecutorG ...

  2. Vue.js 相关知识(基础)

    1. Vue.js 介绍 Vue,读音 /vjuː/,类似于 view),是一套用于构建用户界面的渐进式框架(重点在于视图层). 作者:尤雨溪 注:学习 vue.js 时,一定要抛弃 jQuery 的 ...

  3. printf命令详解

    基础命令学习目录首页 本文是Linux Shell系列教程的第(八)篇,更多shell教程请看:Linux Shell系列教程 在上一篇:Linux Shell系列教程之(七)Shell输出这篇文章中 ...

  4. Kubernetes探索学习005--Kubernetes的Controller模型和ReplicaSet伸缩

    1.Kubernetes的controller pattern 需要认识到Kubernetes操作Pod的逻辑,都是由控制器来完成的. 查看之前写过的nginx-deployment的YAML文件 [ ...

  5. Performance — 前端性能监控利器

    Performance是一个做前端性能监控离不开的API,最好在页面完全加载完成之后再使用,因为很多值必须在页面完全加载之后才能得到.最简单的办法是在window.onload事件中读取各种数据. 大 ...

  6. Python 命令行解析工具 Argparse介绍

    最近在研究pathon的命令行解析工具,argparse,它是Python标准库中推荐使用的编写命令行程序的工具. 以前老是做UI程序,今天试了下命令行程序,感觉相当好,不用再花大把时间去研究界面问题 ...

  7. 转载---VisualStudioCode通过SSH远程编辑文件

    最近需要长期修改远端服务器上的代码,调试.vim操作又不是很6,想到了远程操作的办法,找到一篇好用的bolg,记录一下. 原文链接:https://blog.csdn.net/qq_38401919/ ...

  8. 在Gulp中使用BrowserSync

    博客已迁移至http://zlwis.me. 很早就听说过BrowserSync,也看过一些相关文章,可就是没用过.之前一直在用Gulp开发项目,每次编写完Sass后还要用按F5刷新页面看效果,想想也 ...

  9. 1、数据库与excel表格的数据导入导出

    1.居民用户界面中,excel数据导入导出: 2.其他5张表数据显示到本角色主页的container容器中.

  10. 关于mybatis的思考(3)——ResultMaps的使用

    ResultMap元素在mybatis中非常重要,目的是告诉mybatis将从结果集中取出的数据转换为开发者需要的对象.     UserMapping.xml <!-- selectAll操作 ...