欧拉回路求路径POJ 2230

Watchcow

Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 8841   Accepted: 3854   Special Judge

Description

Bessie‘s been appointed the new watch-cow for the farm. Every night, it‘s her job to walk across the farm and make sure that no evildoers are doing any evil. She begins at the barn, makes her patrol, and then returns to the barn when she‘s done.

If she were a more observant cow, she might be able to just walk each of M (1 <= M <= 50,000) bidirectional trails numbered 1..M between N (2 <= N <= 10,000) fields numbered 1..N on the farm once and be confident that she‘s seen everything she needs to see. But since she isn‘t, she wants to make sure she walks down each trail exactly twice. It‘s also important that her two trips along each trail be in opposite directions, so that she doesn‘t miss the same thing twice.

A pair of fields might be connected by more than one trail. Find a path that Bessie can follow which will meet her requirements. Such a path is guaranteed to exist.

Input

* Line 1: Two integers, N and M.

* Lines 2..M+1: Two integers denoting a pair of fields connected by a path.

Output

* Lines 1..2M+1: A list of fields she passes through, one per line, beginning and ending with the barn at field 1. If more than one solution is possible, output any solution.

Sample Input

4 5
1 2
1 4
2 3
2 4
3 4

Sample Output

1
2
3
4
2
1
4
3
2
4
1

代码分为递归和非递归版本,POJ磁盘满了代码还没交过。。。2018-6-18

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <stack>
 6
 7 using namespace std;
 8 const int MAXN = 1e4 + 7;
 9 const int MAXM = 5e4 + 7;
10
11 int n, m, first[MAXN], sign, vis[MAXN];
12
13 struct Edge {
14     int to, w, next;
15 } edge[MAXM * 4];
16
17 inline void init() {
18     for(int i = 0; i <= n; i++ ) {
19         first[i] = -1;
20         vis[i] = 0;
21     }
22     sign = 0;
23 }
24
25 inline void add_edge(int u, int v, int w) {
26     edge[sign].to = v;
27     edge[sign].w = w;
28     edge[sign].next = first[u];
29     first[u] = sign++;
30 }
31
32 void dfs(int x) {
33     for(int i = first[x]; ~i; i = edge[i].next) {
34         int to = edge[i].to;
35         if(!vis[i]) {
36             vis[i] = 1;
37             dfs(to);
38         }
39     }
40     printf("%d\n", x);
41 }
42
43 int main()
44 {
45     while(~scanf("%d %d", &n, &m)) {
46         init();
47         for(int i = 1; i <= m; i++ ) {
48             int u, v;
49             scanf("%d %d", &u, &v);
50             add_edge(u, v, 1);
51             add_edge(v, u, 1);
52         }
53         dfs(1);
54     }
55
56     return 0;
57 }

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <stack>
 6
 7 using namespace std;
 8 const int MAXN = 1e4 + 7;
 9 const int MAXM = 5e4 + 7;
10
11 int n, m, first[MAXN], sign, vis[MAXN];
12
13 struct Edge {
14     int to, w, next;
15 } edge[MAXM * 4];
16
17 inline void init() {
18     for(int i = 0; i <= n; i++ ) {
19         first[i] = -1;
20         vis[i] = 0;
21     }
22     sign = 0;
23 }
24
25 inline void add_edge(int u, int v, int w) {
26     edge[sign].to = v;
27     edge[sign].w = w;
28     edge[sign].next = first[u];
29     first[u] = sign++;
30 }
31
32 stack<int>st, ans;
33
34 void eulur(int start) {
35     while(!st.empty()) {
36         st.pop();
37     }
38     while(!ans.empty()) {
39         ans.pop();
40     }
41     st.push(start);
42     while(!st.empty()) {
43         int x = st.top(), i = first[x];
44         while(~i && vis[i]) {
45             i = edge[i].next;
46         }
47         if(~i) {
48             st.push(edge[i].to);
49             //vis[i] = vis[i ^ 1] = 1;
50             vis[i] = 1;
51             first[x] = edge[i].next;
52         } else {
53             st.pop();
54             ans.push(x);
55         }
56     }
57 }
58
59
60 int main()
61 {
62     while(~scanf("%d %d", &n, &m)) {
63         init();
64         for(int i = 1; i <= m; i++ ) {
65             int u, v;
66             scanf("%d %d", &u, &v);
67             add_edge(u, v, 1);
68             add_edge(v, u, 1);
69         }
70         eulur(1);
71         while(!ans.empty()) {
72             printf("%d\n", ans.top());
73             ans.pop();
74         }
75     }
76
77     return 0;
78 }



原文地址:https://www.cnblogs.com/Q1143316492/p/9194298.html

时间: 2024-10-29 19:07:11

欧拉回路求路径POJ 2230的相关文章

POJ 1041 John&#39;s trip 无向图的【欧拉回路】路径输出

欧拉回路第一题TVT 本题的一个小技巧在于: [建立一个存放点与边关系的邻接矩阵] 1.先判断是否存在欧拉路径 无向图: 欧拉回路:连通 + 所有定点的度为偶数 欧拉路径:连通 + 除源点和终点外都为偶数 有向图: 欧拉回路:连通 + 所有点的入度 == 出度 欧拉路径:连通 + 源点 出度-入度=1 && 终点 入度 - 出度 = 1 && 其余点 入度 == 出度: 2.求欧拉路径 : step 1:选取起点(如果是点的度数全为偶数任意点为S如果有两个点的度数位奇数取一

POJ 2230 Watchcow &amp;&amp; USACO Watchcow 2005 January Silver (欧拉回路)

题意: Bessie 最近做了农场看守,他每天晚上的工作就是巡视农场并且保证没有坏人破坏农场.从谷仓出发去巡视,并且最终回到谷仓. Bessie 视力不是很好,不能像其他农场的看守一样,对农场的每一条连接不同场地的路走一遍就可以发现是不是有异常情况,他需要每条路都走两遍,并且这两边必须是不同的方向,因为他觉得自己应该不会两次都忽略农场中的异常情况. 每块地之间一定会由至少一条路相连.现在的任务就是帮他制定巡视路线.前提假设一定存在满足题意的路径. 输入: 第一行输入两个数N(2 <= N <=

POJ 2230 Watchcow (欧拉回路)

题目地址:POJ 2230 最普通的欧拉回路.边不重复记录点.不多说. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <stdio.

POJ 2230 Watchcow 欧拉回路题解

本题就是以每个节点和节点之间建路,而且说明是无向图,不过这里有个技巧,就是根据题意把它当成有向图来做,就成了直接查找有向图的欧拉回路就可以了.因为题意是需要每条边都走两遍的,而且每次走的方向相反. 观察出这点,那么这道题就好做啦,直接建图,Feury递归求解就可以了. 建图注意需要建邻接表,不要建矩阵,因为建成矩阵,那么会很大很大,而根据题意,建成邻接表最多只需要5倍的顶点数. 打印的顺序是逆过来打和顺着打都可以的,因为先走那边都可以. #include <stdio.h> #include

[2016-01-27][POJ][2230][Watchcow]

H - 欧拉图 中级者向 Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2230 Description Bessie's been appointed the new watch-cow for the farm. Every night, it's her job to walk across the farm and make s

第K短路径 POJ 2449

第K短路径 POJ 2449 一个朴实的算法是搜索出所有的路径,去第k短. 然后我们尝试能否让第一次到底的最短路径,第二次到达的第二短.其实是给A*. 我们维护已经走了多远和距离终点还有多远的距离和小的优先走,就能达到上述要求. 距离终点还有多远反向建图,求一次最短路即可. #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <qu

POJ 2230 解题报告

分析: 基础的欧拉路算法,变化在于要求每条边正向和反向各走一遍. 链式前向星构图,只要标记走过的单向边,边找边输出即可. code #include <iostream> #include <cstdio> using namespace std; struct node { int v, ne; } edge[100009]; int head[10009], vis[100009], cnt = 1; int n, m, x, y; void addedge (int u, i

[欧拉回路] poj 2230 Watchcow

题目链接: http://poj.org/problem?id=2230 Watchcow Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 6055   Accepted: 2610   Special Judge Description Bessie's been appointed the new watch-cow for the farm. Every night, it's her job to walk acr

poj 1780 , poj 1392 欧拉回路求前后相互衔接的数字串

两道题目意思差不多 第一题是10进制 , 第二题是2进制的 都是利用欧拉回路的fleury算法来解决 因为我总是希望小的排在前面,所以我总是先将较小数加入栈,再利用另一个数组接收答案,但是这里再从栈中导出来答案要倒一下了,这一点要注意 poj 1780 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 using namespace std; 5 #define N 1000010 6 7 int