欧拉路径相关知识

来源:互联网 发布:域名 web名词解释 编辑:程序博客网 时间:2024/06/09 23:30

首先说说概念:
设G是无向连通图, 则称经过G的每条边一次且仅一次的路径为欧拉通路.
如果欧拉通路是回路, 那么该回路为欧拉回路.
具有欧拉回路的无向图G称为欧拉图.

如果G是有向图, 并且G的基图联通. 那么由上面的定义中所有的名次加上一个有向即可…

相关定理:
1: 无向图G存在欧拉通路的充要条件是: G为连通图, 并且G仅有两个奇度节点或者无奇度节点
2: 当G有两个奇度节点的连通图时, G的欧拉桐庐必以次两个节点为端点.
3: G为欧拉图(G存在欧拉回路)的充要条件是G为无奇度节点的连通图.

4: 有向图D存在欧拉通路的充要条件是: D为有向图, D的基图连通, 并且所有顶点的出度和入度相等; 或者除两个点外, 其余顶点的出度和入度都相等, 而这两个顶点中一个顶点出入度之差为1, 另一个为-1.
5: 若有这两个点, 那么一定是以出入度之差为1作为起点, 另一个作为终点.
6: D为有向欧拉图(D存在有向欧拉回路)的充要条件是D的基图连通, 并且所有的顶点出入度都相等.

用以上定理可以解决一些直接判定问题. 而这些问题的关键在于如何把问题转化为图的模型. 这些多做题就自然有这种感觉.

那么还有一类问题, 就是如何输出欧拉路径了. 普遍的方法有两种, 一是DFS爆搜每一条边, 走不通就不走, 直到搜出正解. 还有一种是叫弗洛莱算法. 它的思想是, 从出发点出发开始寻找可以扩展的边, 并且对于当前的情况, 优先找不是 桥 的边. 然后递归输出, 即可. 模板如下: 因为涉及到了删边的处理, 那么用临接矩阵存图.
模板题

Fleury算法板子(只是对于图中有点,边无信息的):

/** @Cain*/const int maxn = 1e3+5;int cas=1;int du[maxn],path[maxn];int mapp[maxn][maxn];int n,m,top=0;void dfs(int u){    for(int i=1;i<=n;i++){        if(mapp[u][i]){            mapp[u][i]--; mapp[i][u]--; //选过的边不能再选.            dfs(i);        }    }    path[top++] = u;}void solve(){    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++){        int u,v; scanf("%d%d",&u,&v);        mapp[u][v]++; mapp[v][u]++;  //路可能不止一条.        du[u]++; du[v]++;    }    int flag = 1;    for(int i=1;i<=n;i++){        if(du[i] & 1) {            dfs(i); flag = 0;            break;        }    }    if(flag) dfs(1);   //欧拉回路的情况.    for(int i=0;i<top;i++){        printf("%d%c",path[i],i==top-1?'\n':' ');    }}

一般标记边的可以用链式前向星做, 一般对于边上有信息的, 点不重要的…..
随机应变…(板子在另外的博客里面)

暂时就姜这么多了…..