时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

在上一回中小Hi和小Ho控制着主角收集了分散在各个木桥上的道具,这些道具其实是一块一块骨牌。

主角继续往前走,面前出现了一座石桥,石桥的尽头有一道火焰墙,似乎无法通过。

小Hi注意到在桥头有一张小纸片,于是控制主角捡起了这张纸片,只见上面写着:

将M块骨牌首尾相连放置于石桥的凹糟中,即可关闭火焰墙。切记骨牌需要数字相同才能连接。
——By 无名的冒险者

小Hi和小Ho打开了主角的道具栏,发现主角恰好拥有M快骨牌。

小Ho:也就是说要把所有骨牌都放在凹槽中才能关闭火焰墙,数字相同是什么意思?

小Hi:你看,每一块骨牌两端各有一个数字,大概是只有当数字相同时才可以相连放置,比如:

小Ho:原来如此,那么我们先看看能不能把所有的骨牌连接起来吧。

提示:Fleury算法求欧拉路径

输入

第1行:2个正整数,N,M。分别表示骨牌上出现的最大数字和骨牌数量。1≤N≤1,000,1≤M≤5,000

第2..M+1行:每行2个整数,u,v。第i+1行表示第i块骨牌两端的数字(u,v),1≤u,v≤N

输出

第1行:m+1个数字,表示骨牌首尾相连后的数字

比如骨牌连接的状态为(1,5)(5,3)(3,2)(2,4)(4,3),则输出"1 5 3 2 4 3"

你可以输出任意一组合法的解。

样例输入
5 5
3 5
3 2
4 2
3 4
5 1
样例输出
1 5 3 4 2 3

小Ho:这种简单的谜题就交给我吧!

小Hi:真的没问题么?

<10分钟过去>

小Ho:啊啊啊啊啊!搞不定啊!!!骨牌数量一多就乱了。

小Hi:哎,我就知道你会遇到问题。

小Ho:小Hi快来帮帮我!

小Hi:好了,好了。让我们一起来解决这个问题。

<小Hi思考了一下>

小Hi:原来是这样。。。小Ho你仔细观察这个例子:

因为相连的两个数字总是相同的,不妨我们只写一次,那么这个例子可以写成:3-2-4-3-5-1。6个数字刚好有5个间隙,每个间隙两边的数字由恰好对应了一块骨牌。

如果我们将每一个数字看作一个点,每一块骨牌看作一条边。你觉得是怎么样的呢?

小Ho:以这个例子来说的话,就是:

要把所有的骨牌连起来,也就是把所有的边都走一次。咦,这不是欧拉路问题么!

小Hi:没错,这问题其实就是一个欧拉路的问题,不过和上一次不一样的在于,这一次我们要找出一条欧拉路径。

小Ho:那我们应该如何来找一条路径呢?

小Hi:我们还是借用一下上次的例子吧

使用我们上一次证明欧拉路判定的方法,我们在这个例子中找到了2条路径:

L1: 4-5-2-3-6-5
L2: 2-4-1-2

假设我们栈S,记录我们每一次查找路径时的结点顺序。当我们找到L1时,栈S内的情况为:

S: 4 5 2 3 6 5 [Top]

此时我们一步一步出栈并将这些边删除。当我们到节点2时,我们发现节点2刚好是L1与L2的公共节点。并且L2满足走过其他边之后回到了节点2。如果我们在这个地方将L2先走一遍,再继续走L1不就刚好走过了所有边么。

而且在上一次的证明中我们知道,除了L1之外,其他的路径L2、L3...一定都满足起点与终点为同一个点。所以从任意一个公共节点出发一定有一条路径回到这个节点。

由此我们得到了一个算法:

  1. 在原图中找一个L1路径

  2. 从L1的终点往回回溯,依次将每个点出栈。并检查当前点是否还有其他没有经过的边。若存在则以当前点为起点,查找L2,并对L2的节点同样用栈记录重复该算法。

  3. 当L1中的点全部出栈后,算法结束。

在这里我们再来一个有3层的例子:

在这个例子中:

L1: 1-2-6-5-1
L2: 2-3-7-2
L3: 3-4-8-3

第一步时我们将L1压入栈S,同时我们用一个数组Path来记录我们出栈的顺序:

S: [1 2 6 5 1]
Path:

然后出栈到节点2时我们发现了2有其他路径,于是我们把2的另一条路径加入:

S: 1 [2 3 7 2]
Path: 1 5 6

此时L2已经走完,然后再开始弹出元素,直到我们发现3有其他路径,同样压入栈:

S: 1 2 [3 4 8 3]
Path: 1 5 6 2 7

之后依次弹出剩下的元素:

S:
Path: 1 5 6 2 7 3 8 4 3 2 1

此时的Path就正好是我们需要的欧拉路径。

小Ho:原来这样就能求出欧拉路,真是挺巧妙的。

小Hi:而且这个算法在实现时也有很巧妙的方法。因为DFS本身就是一个入栈出栈的过程,所以我们直接利用DFS的性质来实现栈,其伪代码如下:

DFS(u):
While (u存在未被删除的边e(u,v))
删除边e(u,v)
DFS(v)
End
PathSize ← PathSize + 1
Path[ PathSize ] ← u

小Ho:这代码好简单,我觉得我可以实现它!

小Hi:那么实现就交给你了

小Ho:没问题!交给我吧

 
 #include <bits/stdc++.h>
using namespace std; int N, M;
int u, v;
vector<vector<int>> graph;
vector<int> inDegree;
vector<int> path; void dfs(int u) {
for (int v = ; v <= N; ++v) {
if (graph[v][u] == ) continue;
--graph[v][u];
--graph[u][v];
dfs(v);
}
path.push_back(u);
} int main() {
while (cin >> N >> M) {
graph.assign(N + , vector<int>(N + , ));
inDegree.assign(N + , );
path.clear();
for (int i = ; i < M; ++i) {
cin >> u >> v;
++graph[u][v];
++graph[v][u];
++inDegree[v];
++inDegree[u];
}
int start = ;
for (int i = ; i <= N; ++i) if (inDegree[i] & ) {
start = i;
break;
}
dfs(start);
for (int i = ; i < path.size(); ++i) {
cout << path[i] << " ";
}
cout << endl;
}
return ;
}

[hihoCoder] 第五十周: 欧拉路·二的更多相关文章

  1. hihocoder 1181 欧拉路.二

    传送门:欧拉路·二 #1181 : 欧拉路·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回中小Hi和小Ho控制着主角收集了分散在各个木桥上的道具,这些道具其 ...

  2. hiho欧拉路·二 --------- Fleury算法求欧拉路径

    hiho欧拉路·二 分析: 小Ho:这种简单的谜题就交给我吧! 小Hi:真的没问题么? <10分钟过去> 小Ho:啊啊啊啊啊!搞不定啊!!!骨牌数量一多就乱了. 小Hi:哎,我就知道你会遇 ...

  3. [hihoCoder] 第四十九周: 欧拉路·一

    题目1 : 欧拉路·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho最近在玩一个解密类的游戏,他们需要控制角色在一片原始丛林里面探险,收集道具,并找到最 ...

  4. hiho一下 第四十九周 欧拉路

    http://hihocoder.com/contest/hiho49/problem/1 给定无孤立结点图G,若存在一条路,经过图中每边一次且仅一次,该条路称为欧拉路. 一个无向图存在欧拉路当且仅当 ...

  5. hihoCoder #1181: 欧拉路·二 (输出路径)

    题意: 给定一个图,要求打印出任一条欧拉路径(保证图肯定有欧拉路). 思路: 深搜的过程中删除遍历过的边,并在回溯时打印出来.在深搜时会形成多个环路,每个环都有一个或多个结点与其他环相扣,这样就可以产 ...

  6. hiho一下 第四十九周 欧拉路&#183;一

    [题目链接]:click here~~ 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描写叙述 小Hi和小Ho近期在玩一个解密类的游戏.他们须要控制角色在一片原始丛林里面探险 ...

  7. hihocoder 第五十二周 高斯消元·二【高斯消元解异或方程 难点【模板】】

    题目地址:http://hihocoder.com/contest/hiho57/problem/1 输入 第1..5行:1个长度为6的字符串,表示该行的格子状态,1表示该格子是亮着的,0表示该格子是 ...

  8. [hihoCoder] 第五十二周: 连通性·一

    题目1 : 连通性·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 还记得上次小Hi和小Ho学校被黑客攻击的事情么,那一次攻击最后造成了学校网络数据的丢失.为了避免再 ...

  9. 【HIHOCODER 1181】欧拉路·二

    描述 在上一回中小Hi和小Ho控制着主角收集了分散在各个木桥上的道具,这些道具其实是一块一块骨牌. 主角继续往前走,面前出现了一座石桥,石桥的尽头有一道火焰墙,似乎无法通过. 小Hi注意到在桥头有一张 ...

随机推荐

  1. Linux下使用logrotate实现日志切换

    运维过程中经常会发现一些 C 程序,每天会生产这样的日志: /home/admin/app_name/logs/access_log 那么天长地久,如果这个程序不会自动去轮转这个日志,那么这个日志文件 ...

  2. Java之创建对象>3.Enforce the singleton property with a private constructor or an enum type

     1. 通过一个公开的字段来获取单例 // Singleton with public final field public class Elvis { public static final Elv ...

  3. 【DB2】监控动态SQL语句

    一.db2监控动态SQL(快照监控) db2示例用户登陆后,使用脚本语句db2 get snapshot for all on dbname>snap.out 也可以使用db2 get snap ...

  4. XPAGES 中CGI变量的获取

    In XPages, CGI variables are also available, but you need to write some code to get them via the JSF ...

  5. 基于Echarts的中国地图数据展示

    发布时间:2018-10-31   技术:javascript+html5+canvas   概述 基于echarts的大数据中国地图展示,结合API定制,开发样式,监听鼠标事件,实现带参数路由跳转等 ...

  6. (原)torch,caffe,python中读入数据的默认范围

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6554388.html 之前torch(image.load).caffe(默认的).python(使用 ...

  7. Ubuntu 12.04安装VMware Workstation8.0.3

    2012-06-18 12:52   Ubuntu安装VMware Workstation8.0.3   由于使用Ubuntu的人比较少,网上关于Ubuntu的资料也很少,笔者在安装VMware Wo ...

  8. IO 多路复用是什么意思?

    在同一个线程里面, 通过拨开关的方式,来同时传输多个I/O流, (学过EE的人现在可以站出来义正严辞说这个叫“时分复用”了). 什么,你还没有搞懂“一个请求到来了,nginx使用epoll接收请求的过 ...

  9. Linux 操作MySQL常用命令行(转)

    注意:MySQL中每个命令后都要以分号:结尾. 1.显示数据库 mysql> show databases; +----------+ | Database | +----------+ | m ...

  10. 如何使用Git上传项目代码到github

    这是我第一次应用git,以下仅供git的初学者参考.     github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要公开.这对于一般人来说 ...