码迷,mamicode.com
首页 > 其他好文 > 详细

欧拉回路-骑马修栅栏

时间:2014-07-22 00:33:34      阅读:293      评论:0      收藏:0      [点我收藏+]

标签:style   os   io   for   re   c   

#include<iostream>
#include<string.h>
using namespace std;
int f[1050][1050],d[1050],res[1550000];
int n,j=0,k=0,m=0;
void search(int z)  
{
for(int i=1;i<=m;i++)
if(f[z][i]>0)
{f[z][i]--;
f[i][z]--;
search(i);
}
j++;
res[j]=z;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
{ int x,y;
cin>>x>>y;
f[x][y]++;
f[y][x]++;
d[x]++;d[y]++;
m=max(max(x,m),y);
}
for(int i=1;i<=m;i++)
if(d[i]%2!=0) 
{k=i;break;}
if(k==0)
{
for(int i=1;i<=n;i++)
if(d[i])
{k=i;break;}}
search(k);
for(int i=j;i>0;i--)
cout<<res[i]<<endl;
return 0;
}

本渣写的该题的程序。思路大致是剽窃wikioi上本题的某位选手的。

现在,让我来重温思路,加强理解 ,巩固记忆。

f[x][y]++;
f[y][x]++;  这两句很妙,和后面的减减堪称是本算法的点睛之笔(个人拙见,勿喷)。该句话是记录出现过的路径,有的就标为1.而函数中的减减,则是该路已走过一次后,便标为0,使得不会重复走。理解了这一点,该算法便理解大半了。

d[x],d[y]是记录该点一共有几条线(好像叫出线?)来辨认奇度点和偶度点(出线为奇或偶)。

m=max(max(x,m),y);至于这一句,则是在记录出现的点的最大值,确定点的范围。

for(int i=1;i<=m;i++)
if(d[i]%2!=0) 
{k=i;break;}
if(k==0)
{
for(int i=1;i<=n;i++)
if(d[i])
{k=i;break;}}  这一句这是寻找有没有奇度点(不明白奇度点对于欧拉回路的含义可自行百度),有奇度点就记录小的奇度点。没有则记录最小的偶度点。

然后,找到了最小的奇(偶)度点,就可以开始运用函数啦!

void search(int z)  
{
for(int i=1;i<=m;i++)
if(f[z][i]>0)
{f[z][i]--;
f[i][z]--;
search(i);
}
j++;
res[j]=z;
}      从最小的奇(偶)度点开始,寻找点的大小和它最接近的点组成的线,然后再把该线记录为0,避免重复。下面的J++是记录该点出现的第几次数。

用res[]保存。

至于最后面为啥要倒序输出,我还不懂,。等懂了我再来补上。

欢迎高人指点,鄙人实乃新手。

欧拉回路-骑马修栅栏,布布扣,bubuko.com

欧拉回路-骑马修栅栏

标签:style   os   io   for   re   c   

原文地址:http://www.cnblogs.com/changjie/p/3857953.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!