欧拉路小结 JZYZOJ1210 骑马修栅栏

Posted 鲸头鹳

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了欧拉路小结 JZYZOJ1210 骑马修栅栏相关的知识,希望对你有一定的参考价值。

现在写到欧拉路,理解起来并不算特别困难...吧...

但是非常恶心的是每次都要调试半天,做不到一遍两遍就能ac
每次写程序都对于程序的整体构架没有清晰的思路,想到哪里写到哪里真的是个非常差的习惯[尽管在写不出来的时候非常有用],所以快点改掉吧.
似乎也没有什么特别困难的部分,相关的题在oj上是p1209-p1211
数组一定要记得稍微开大一点,不要顺手就打一个数据范围上去,很初级也很常见的错误
应该深入理解一下dfs之后记录的作用,但是我到现在还不理解
以p1210为例
 
骑马修栅栏  
     
     
  描述 Description  
  农民John每年有很多栅栏要修理。他总是骑着马穿过每一个栅栏并修复它破损的地方。 
John是一个与其他农民一样懒的人。他讨厌骑马,因此从来不两次经过同一个栅栏。你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次。John能从任何一个顶点(即两个栅栏的交点)开始骑马,在任意一个顶点结束。 
每一个栅栏连接两个顶点,顶点用1到500标号(虽然有的农场并没有500个顶点)。一个顶点上可连接任意多(>=1)个栅栏。所有栅栏都是连通的(也就是你可以从任意一个栅栏到达另外的所有栅栏)。 
你的程序必须输出骑马的路径(用路上依次经过的顶点号码表示)。我们如果把输出的路径看成是一个500进制的数,那么当存在多组解的情况下,输出500进制表示法中最小的一个 (也就是输出第一个数较小的,如果还有多组解,输出第二个数较小的,等等)。 
     
     
  输入格式 Input Format  
  第1行: 一个整数F(1 <= F <= 1024),表示栅栏的数目 
第2到F+1行: 每行两个整数i, j(1 <= i,j <= 500)表示这条栅栏连接i与j号顶点。 
     
     
  输出格式 Output Format  
  输出应当有F+1行,每行一个整数,依次表示路径经过的顶点号。注意数据可能有多组解,但是只有上面题目要求的那一组解是认为正确的。
     
     
  样例输入 Sample Input  
   
     
     
  样例输出 Sample Output  
   
     
     
  时间限制 Time Limitation  
  1s
     
     
  注释 Hint  
  字典序最小的欧拉路
给一个例子:
技术分享
     
     
  来源 Source  
  usaco 3.3.1
     
     
 
Flag
  Accepted
题号
  P1210
  图结构
通过
  58人
提交
  205次
通过率
  28%
难度
  1
 
     
     
 
提交 讨论 题解 数据
 
     

代码如下[里面有非常不必要的东西..但是都这样了也懒得改回去了]
 
技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int maxn=0;
 7 int tail=0;
 8 int flag=0;
 9 int f,ss;
10 int sta[510]={};
11 int sum[510]={};
12 int woc[510][510]={};
13 int mos[510][510]={};
14 int cun[510]={};
15 void mydfs(int x,int k){
16     for(int i=1;i<=mos[x][0];i++){
17         int w=mos[x][i];
18         if(woc[x][w]!=0){
19             woc[x][w]-=1;
20             woc[w][x]-=1;
21             mydfs(w,k+1);
22             cun[ss--]=w;//这个--肥肠重要,嗯我也不会解释,复习的时候看着理解好了
23                     if(ss==1){
24                 for(int i=2;i<=f+1;i++){
25                     cout<<cun[i]<<endl;
26                 }
27             }
28         }
29     }
30 }
31 int main(){
32     cin>>f;
33     ss=f+1;
34     for(int i=1;i<=f;i++){
35         int x,y;
36         cin>>x>>y;
37         if(x>maxn){
38             maxn=x;
39         }
40         if(y>maxn){
41             maxn=y;
42         }
43         sum[x]++;
44         sum[y]++;
45         mos[y][++mos[y][0]]=x;
46         mos[x][++mos[x][0]]=y;
47         woc[x][y]+=1;
48         woc[y][x]+=1;
49     }
50     for(int i=1;i<=maxn;i++){
51         if(mos[i][0]!=0){
52             sort((int*)mos+510*i+1,(int*)mos+510*i+mos[i][0]+1);
53         }
54     }
55     int f1=0;
56     for(int i=1;i<=500;i++){
57         if(sum[i]%2==1){
58             f1=i;
59             break;
60         }
61     }
62     if(f1!=0){
63         cout<<f1<<endl;
64         mydfs(f1,0);
65     }
66     else{
67         cout<<1<<endl;
68         mydfs(1,0);
69     }
70     return 0;
71 }
View Code

 








以上是关于欧拉路小结 JZYZOJ1210 骑马修栅栏的主要内容,如果未能解决你的问题,请参考以下文章

P2731 骑马修栅栏 欧拉函数

骑马修栅栏

luogu P2731 骑马修栅栏 Riding the Fences | 欧拉道路

欧拉回路--P2731 骑马修栅栏 Riding the Fences

P2731 骑马修栅栏 Riding the Fences

骑马修栅栏--一种较为慢的做法