洛谷图论入门题--基本题必做 图的遍历—3.骑马修栅栏(fence)

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

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

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

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

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

 1 #include<iostream>
 2 #include<cmath>
 3 using namespace std;
 4 int du[10050] ={0}, ola[10050] ={0}, n , start  = 0,
 5 //du[]用来存每个点的度数 ,ola[]用来存储路径 ,start查找最小的开始点 
 6     map[1050][1050] ={0}, m = 0 , tot = 0;
 7 void dfs(int k){
 8     for(int i = 1 ; i <= m ; i++){
 9         if(map[k][i] != 0){
10             map[k][i] --;
11             map[i][k] --;
12             //避免重复走 
13             dfs(i);
14         }
15     }
16     tot++;
17     ola[tot] = k;
18 //深搜每个边 
19 }
20 
21 int main(){
22     int x , y;
23     cin>>n;
24     for(int i = 1 ; i <= n ; i++){
25         cin>>x>>y;
26         map[x][y] ++;
27         map[y][x] ++;
28         //至于为什么是 map[][]++我们等下会给出一组数据 
29         du[x]++;
30         du[y]++;
31         m = max(x , m);
32         m = max(m , y);
33         //寻找最大的边
34     }
35     for(int i = 1 ; i <= m ; i ++) {
36            if(du[i] % 2 == 1){
37                start = i;
38                break;
39            }
40     }
41     //找奇数边 
42     if(start == 0){
43         for(int i = 1 ; i <= m ; i ++){
44             if(du[i] > 0){
45                 start = i;
46                 break;
47             }
48         }
49     }
50     //如果全是偶数就找最小的偶数 
51     dfs(start);
52     for(int i = tot ; i >= 1 ; i--){
53         //最后几个87分是最坑的,题目中让%500,但是500%500=0 
54         //一个点就是这么坑,500不取模,所以让边大于500再%500 
55         if(ola[i]>500)
56         ola[i] %= 500;
57         cout<<ola[i]<<endl;
58     }
59     //结束 
60     return 0;
61 }
View Code

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

posted @ 2017-03-31 19:39  秦时、长浩  阅读(803)  评论(0编辑  收藏  举报