zoukankan      html  css  js  c++  java
  • 欧拉路与欧拉回路

    欧拉路与欧拉回路的定义

    如果一张图中的一个路径包括每个边恰好一次,则该路径称为欧拉路

    如果一个回路是欧拉路,则称为欧拉回路

    欧拉路与欧拉回路的存在条件

    • 对于无向联通图
      • 欧拉路:只有两个点为奇点的无向图存在欧拉路(起点和终点为两个奇点)。
      • 欧拉回路:没有奇点的无向图存在欧拉回路。
    • 对于有向联通图
      • 欧拉路:一个顶点的出度-入度=1,另一个顶点的入度-出度=1,其他所有点入度等于出度时存在欧拉路(起点为出度-入度=1的点,终点为入度-出度=1的点)。
      • 欧拉回路:所有点的入度等于出度时存在欧拉回路。

    如何求解欧拉路与欧拉回路

    我们从确定的起点出发(欧拉回路可以从任意一个节点出发),然后枚举每一条与当前节点相连的边,不停地向下一个节点走,并把走过的边从图中删去。每次把到达当前节点所经过的边加入统计答案的(res[) (])数组中,可以证明,这样一定能找到一组合法的解。

    代码

    inline void dfs(int x,int lst)//dfs跑欧拉回路(无向图版)
    {
    	register int &i=lnk[x];//注意,此处的i前面要加一个&,这样就可以不停修改lnk[x],起到一定的优化效果
    	for(;i;i=e[i].nxt)//枚举下一条边
    	{
    		if(vis[i+1>>1]) continue;//如果这条边已经访问过了,就跳过
    		vis[i+1>>1]=1,dfs(e[i].to,i&1?(i+1>>1):-(i+1>>1));//标记这条边已访问,搜索下一个点,记录是由这条边通往下一个点的
    	}
    	if(lst) res[++res_]=lst;//如果不是起点,就记录下到达当前节点的边
    }
    
    inline void dfs(int x,int lst)//dfs跑欧拉回路(有向图版),大致思想同上
    {
    	register int &i=lnk[x];
    	for(;i;i=e[i].nxt)
    	{
    		if(vis[i]) continue;
    		vis[i]=1,dfs(e[i].to,i);
    	}
    	if(lst) res[++res_]=lst;
    }
    

    例题

    【洛谷1341】无序字母对

  • 相关阅读:
    VM VirtualBox安装Centos6.5
    桥接
    程序员工作心法
    策略模式-鸭子怎么飞-实例
    策略模式-用什么方式去上班呢 实例
    观察者模式-订报纸,语音呼叫系统实例
    门面(Facade)模式--医院,保安系统实例
    Promise实例的resolve方法
    Promise实例的any方法
    Promise实例的race方法
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/EulerRoad.html
Copyright © 2011-2022 走看看