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】无序字母对

  • 相关阅读:
    Remove Element
    C++ 一些STL
    Two Pointers/hash/3Sum/4Sum类题目
    动态规划
    UVa 12657 双向链表
    并行运行环境
    多线程编程
    HTML XML CSS JS 迅速学习
    UVa 11988 数组模拟链表
    静态链表
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/EulerRoad.html
Copyright © 2011-2022 走看看