欧拉回路--P2731 骑马修栅栏 Riding the Fences
实在懒得复制题干了 *传送
1.定义
2. 定理及推论
无向图G存在欧拉通路的充要条件是:
1) 当G是仅有两个奇度结点的连通图时,G的欧拉通路必以此两个结点为端点。
2) 当G是无奇度结点的连通图时,G必有欧拉回路。
有向图D存在欧拉通路的充要条件是:
推论2:
1) 当D除出、入度之差为1,-1的两个顶点之外,其余顶点的出度与入度都相等时,D的有向欧拉通路必以出、入度之差为1的顶点作为始点,以出、入度之差为-1的顶点作为终点。
2) 当D的所有顶点的出、入度都相等时,D中存在有向欧拉回路
求解:
A. DFS搜索求解欧拉回路
基本思路:利用欧拉定理判断出一个图存在欧拉回路或欧拉通路后,选择一个正确的起始顶点,用DFS算法遍历所有的边(每一条边只遍历一次),遇到走不通就回退。在搜索前进方向上将遍历过的边按顺序记录下来。这组边的排列就组成了一条欧拉通路或回路。
- #include<cstdio>
- #include<stdio.h>
- #include<cstring>
- #include<algorithm>
- #define MAX 2010
- using namespace std;
- int maps[MAX][MAX];
- int in[MAX];
- int t[MAX];
- int flag;
- int k;
- int Max,Min;
- int DFS(int x)
- {
- int i;
- for(i=Min;i<=Max;i++)
- {
- if(maps[x][i])///从任意一个与它相连的点出发
- {
- maps[x][i]--;///删去遍历完的边
- maps[i][x]--;
- DFS(i);
- }
- }
- t[++k]=x;///记录路径,因为是递归所有倒着记
- }
- int main()
- {
- int n,i,x,y;
- Max=-;
- Min=;
- flag=;
- scanf("%d",&n);
- ;i<=n;i++)
- {
- scanf("%d%d",&x,&y);
- maps[x][y]++;
- maps[y][x]++;
- Max=max(x,max(y,Max));
- Min=min(x,min(y,Min));
- in[x]++;
- in[y]++;
- }
- for(i=Min;i<=Max;i++)
- {
- )///存在奇度点,说明是欧拉通路
- {
- flag=;
- DFS(i);
- break;
- }
- }
- if(!flag)///全为偶度点,从标号最小的开始找
- {
- DFS(Min);
- }
- ;i--)
- {
- printf("%d\n",t[i]);
- }
- ;
- }
B. Fleury(佛罗莱)算法
- #include <cstdlib>
- #include <cstring>
- #include <cstdio>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- ];
- int top;
- int N,M;
- ][];
- void dfs(int x)
- {
- int i;
- top++;
- ans[top]=x;
- ; i<=N; i++)
- {
- )
- {
- mp[x][i]=mp[i][x]=;///删除此边
- dfs(i);
- break;
- }
- }
- }
- void fleury(int x)
- {
- int brige,i;
- top=;
- ans[top]=x;///将起点放入Euler路径中
- )
- {
- brige=;
- ; i<=N; i++) /// 试图搜索一条边不是割边(桥)
- {
- )///存在一条可以扩展的边
- {
- brige=;
- break;
- }
- }
- if (!brige)/// 如果没有点可以扩展,输出并出栈
- {
- printf("%d ", ans[top]);
- top--;
- }
- else /// 否则继续搜索欧拉路径
- {
- top--;///为了回溯
- dfs(ans[top+]);
- }
- }
- }
- int main()
- {
- int x,y,deg,num,start,i,j;
- scanf("%d%d",&N,&M);
- memset(mp,,sizeof (mp));
- ;i<=M; i++)
- {
- scanf("%d%d",&x,&y);
- mp[x][y]=;
- mp[y][x]=;
- }
- num=;
- start=;///这里初始化为1
- ; i<=N; i++)
- {
- deg=;
- ; j<=N; j++)
- {
- deg+=mp[i][j];
- }
- ==)///奇度顶点
- {
- start=i;
- num++;
- }
- }
- ||num==)
- {
- fleury(start);
- }
- else
- {
- puts("No Euler path");
- }
- ;
- }
那这道题就是一个欧拉回路的板子
- #include<iostream>
- #include<cstdio>
- #include<cmath>
- using namespace std;
- ][];//记录两个点之间的路径个数
- ];//辅助记录奇点
- ];//记录路径
- ;
- ,Min=1e9;
- int DFS(int x)
- {
- int i;
- for(i=Min;i<=Max;i++)
- {
- if(map[x][i])
- {
- map[x][i]--;
- map[i][x]--;
- DFS(i);
- }
- }
- t[++k]=x;
- }
- int main()
- {
- scanf("%d",&n);
- ;i<=n;++i)
- {
- scanf("%d%d",&x,&y);
- map[x][y]++;
- map[y][x]++;
- du[x]++;
- du[y]++;
- Max=max(Max,max(x,y));
- Min=min(Min,min(x,y));
- }
- ;
- ;i<=Max;++i)
- {
- )
- {
- start=i;
- break;
- }
- }
- DFS(start);
- ;i--)
- {
- printf("%d\n",t[i]);
- }
- ;
- }
欧拉回路--P2731 骑马修栅栏 Riding the Fences的更多相关文章
- P2731 骑马修栅栏 Riding the Fences 题解(欧拉回路)
题目链接 P2731 骑马修栅栏 Riding the Fences 解题思路 存图+简单\(DFS\). 坑点在于两种不同的输出方式. #include<stdio.h> #define ...
- 洛谷P2731 骑马修栅栏 Riding the Fences
P2731 骑马修栅栏 Riding the Fences• o 119通过o 468提交• 题目提供者该用户不存在• 标签USACO• 难度普及+/提高 提交 讨论 题解 最新讨论 • 数据有问题题 ...
- 洛谷 P2731 骑马修栅栏 Riding the Fences 解题报告
P2731 骑马修栅栏 Riding the Fences 题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样 ...
- 洛谷 P2731 骑马修栅栏 Riding the Fences
P2731 骑马修栅栏 Riding the Fences 题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样 ...
- P2731 骑马修栅栏 Riding the Fences
题目描述 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次.John能从任何一个顶 ...
- luogu P2731 骑马修栅栏 Riding the Fences
入度为奇数的点,搜他. 最好邻接矩阵... #include<cstdio> #include<iostream> #define R register int using n ...
- LG2731 骑马修栅栏 Riding the Fences
题意 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次.John能从任何一个顶点( ...
- 「USACO」「LuoguP2731」 骑马修栅栏 Riding the Fences(欧拉路径
Description Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编 ...
- USACO Section 3.3 骑马修栅栏 Riding the Fences
题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个 ...
随机推荐
- 小程序view标签靠右方法
第一种:不浮动靠右 text-align:right; 第二种:浮动靠右 float:right;
- 通过JAVA反射修改JDK1.6*当中DNS缓存内容
时间 2012-05-28 17:09:03 Taobao QA Team原文 http://qa.taobao.com/?p=15523 为了实现性能压测时的域名动态绑定功能,尝试通过java反 ...
- c/c++ 获取BMP文件信息
#include <stdio.h> #include <string.h> typedef struct BITMAPFILEHEADER { // BMP文件头 u_int ...
- Ternsorflow 学习:006-MNIST进阶 深入MNIST
前言 这篇文章适合实践过MNIST入门的人学习观看.没有看过MNIST基础的人请移步这里 深入MNIST TensorFlow是一个非常强大的用来做大规模数值计算的库.其所擅长的任务之一就是实现以及训 ...
- POJ 3685:Matrix 二分
Matrix Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 5489 Accepted: 1511 Descriptio ...
- day05-Python运维开发基础(双层循环、pass/break/continue、for循环)
# ### 双层循环练习 # 十行十列小星星 j = 0 while j<10: # 逻辑代码写在下面 # 打印一行十个小星星 i = 0 while i<10: print(" ...
- C++面试常见问题——12虚函数
虚函数 虚函数的工作原理 虚函数的实现要求对象携带额外的信息,这些信息用于确定运行时调用哪一个虚函数,这一信息具有一种被称为虚函数表指针(vptr)的指针形式.vptr指向一个被称为虚函数表(vtbl ...
- Day6 - M - 动态逆序对 HYSBZ - 3295
对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删 除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数 I ...
- 项目启动报错:Communications link failure
2017-12-29 10:43:19,776 ERROR [com.alibaba.druid.pool.DruidDataSource] - <init datasource error, ...
- [题解] UVA11426 GCD - Extreme (II)
题面 莫反是不可能莫反的,这辈子都不可能莫反了 题目要求的是 \[ \sum\limits_{i=1}^n \sum\limits_{j=i+1}^n \gcd(i,j) \] 稍微变个亚子 \[ \ ...