洛谷图论入门题--基本题必做 图的遍历—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 }
好吧,这篇博客就先写这么多,毕竟时间有限,同行们看到了这篇随笔的话可以顺便看一个这个友情链接 蒟蒻 http://mrmorning.coding.me/大佬给你们助阵!