山东省济南市历城第二中学——洛谷图论入门题--基本题必做 图的遍历—3.骑马修栅栏(fence)

山东省济南市历城第二中学——洛谷图论入门题--基本题必做 图的遍历—3.骑马修栅栏(fence)山东省济南市历城第二中学——洛谷图论入门题--基本题必做 图的遍历—3.骑马修栅栏(fence)

由于我这个破题提交了十四五遍,所以我决定写篇博客来记录一下。

这个题的题目描述是这样的

山东省济南市历城第二中学——洛谷图论入门题--基本题必做 图的遍历—3.骑马修栅栏(fence)

山东省济南市历城第二中学——洛谷图论入门题--基本题必做 图的遍历—3.骑马修栅栏(fence)

首先一看这个题我瞬间就想到了一笔画问题(欧拉回路)。

对于能够一笔画的图,我们有以下两个定理。
  定理1:存在欧拉路的条件:图是连通的,有且只有2个奇点。
  定理2:存在欧拉回路的条件:图是连通的,有0个奇点。

求欧拉路的算法很简单,使用深度优先遍历即可。时间复杂度O(m+n)

 #include<iostream>
#include<cmath>
using namespace std;
int du[] ={}, ola[] ={}, n , start = ,
//du[]用来存每个点的度数 ,ola[]用来存储路径 ,start查找最小的开始点
map[][] ={}, m = , tot = ;
void dfs(int k){
for(int i = ; i <= m ; i++){
if(map[k][i] != ){
map[k][i] --;
map[i][k] --;
//避免重复走
dfs(i);
}
}
tot++;
ola[tot] = k;
//深搜每个边
} int main(){
int x , y;
cin>>n;
for(int i = ; i <= n ; i++){
cin>>x>>y;
map[x][y] ++;
map[y][x] ++;
//至于为什么是 map[][]++我们等下会给出一组数据
du[x]++;
du[y]++;
m = max(x , m);
m = max(m , y);
//寻找最大的边
}
for(int i = ; i <= m ; i ++) {
if(du[i] % == ){
start = i;
break;
}
}
//找奇数边
if(start == ){
for(int i = ; i <= m ; i ++){
if(du[i] > ){
start = i;
break;
}
}
}
//如果全是偶数就找最小的偶数
dfs(start);
for(int i = tot ; i >= ; i--){
//最后几个87分是最坑的,题目中让%500,但是500%500=0
//一个点就是这么坑,500不取模,所以让边大于500再%500
if(ola[i]>)
ola[i] %= ;
cout<<ola[i]<<endl;
}
//结束
return ;
}

好吧,这篇博客就先写这么多,毕竟时间有限,同行们看到了这篇随笔的话可以顺便看一个这个友情链接   蒟蒻  http://mrmorning.coding.me/大佬给你们助阵!

上一篇:arcgis engine - 添加图例,指北针.


下一篇:关于SSH的那些事