usaco3.3欧拉路的胡乱总结

 找欧拉路,本应该很简单,但是我dfs有问题,应该说是我对找欧拉回路算法的理解有问题,先看下有哪些错误:

if(fengce==N){...} //发现走完N条边就退出

for(i=** to **)

if(...)           //试图剪枝

{

 path[fence]=***;

 g[][]--;

 dfs(***,fence+1);// 在递归过程中记录路径,

 g[][]++;        //回溯

}

这样写path在调试时查看路径变化倒是很方便,但是在第7个点时会发现它一直在回溯。

其实找欧拉路不需要回溯,只要存在欧拉路,不故意去走奇数度的点,总能找到。剪枝也是不必要的,如果试图

在fence不为n的时候剪掉含奇数度点的路径,可能得不到结果。

 正确的做法:

 for(i=0 to **)

if(g[cur][i])

{

 g[cur][i]--;

 dfs(cur);

}

path[fence++]=cur;

在跳出前记录当前节点。这样先跳出的会先进入path数组。若是回路,最先从起点(也是终点)跳出,若不是回路,最先跳出的是终点,它有可能是还没有走完所有边就跳出了,但会继续dfs其它节点,记录path依旧是顺序的。

一个例子。     当前状态 : begin - > cur 

  a                       cur->a(a比b先dfs)           

   \                到a后,原来的路被删了,发现啥也木有usaco3.3欧拉路的胡乱总结, 于是跳出,顺便记录到path  

     cur -begin       于是path[0]=a了
     /\               依然从cur继续dfs, 接下来会把cur->b->c->cur 这条回路走完
     b-c              在cur处开始退出,依次记录路径 cur,b,c,cur,begin

    于是最终path里就是:a,cur,b,c,cur,begin

    逆序输出就是正确路径了.

 

检讨完毕...囧。

本文使用Blog_Backup未注册版本导出,请到soft.pt42.com注册。

你可能感兴趣的:(USACO)