欧拉通路

来源:互联网 发布:企业样本设计制作软件 编辑:程序博客网 时间:2024/05/01 18:22


抽象模型:

现在给你一副无向图。 寻找一条包含所有边的路径,其中每一条边只经过一次。这被叫做欧拉通路。若这条路径的起点与终点为同一点,则为欧拉回路。


算法:

判定一个图是否存在欧拉通路或欧拉回路比较容易,这里提供两种不同的判定法则。

定理1:一个图有欧拉回路当且仅当它是连通的(即不包括0度的结点)

且每个结点都有偶数度。 

定理2:一个图有欧拉通路当且仅当它是连通的且除两个结点外,

其他结点都有偶数度。 

定理3:在定理2的条件下,含奇数度的两个结点中,一个必为欧拉通路的起点,

另一个必为终点。


此算法的基本思想是从图中的某个结点出发求出一个能回到该结点的路径。现在,该路径已被加入(根据它的结果,逆序存放)。检验在该路径中的所有结点的每条边是否已被应用。若某个结点存在未被应用的边,则算法进一步找出一条从此结点的这条边开始的新回路,并将这个新的回路连入原路径中。算法一直运行到最初的路径中的所有结点的每一条边都已被应用。既然改图是连通的,这也就表明图中所有的边都已经被应用,所以最终结果也就是欧拉回路。

更加正式的说,寻找图的欧拉回路的方法是选取一个起点,并对它进行递归,递归的步骤为:

  • 选取一个起点并在此结点上,按以下步骤递归:
    • 若此结点无邻结点,则添加该结点到回路中并退出。
    • 若此结点有邻结点,则生成一个邻结点表并对表中的结点进行操作(遍历一个点,删除一个点)直到列表为空。最后将处理的结点加入回路中。
  • 对表中结点的操作为:删去当前处理的结点(指的是当前递归下的结点)与表中的结点相连的边,然后对这个结点进行递归。


伪代码:
# circuit is a global array   find_euler_circuit     circuitpos = 0     find_circuit(node 1) # nextnode and visited is a local array# the path will be found in reverse order  find_circuit(node i)     if node i has no neighbors then      circuit(circuitpos) = node i      circuitpos = circuitpos + 1    else      while (node i has neighbors)          pick a random neighbor node j of node i          delete_edges (node j, node i)          find_circuit (node j)      circuit(circuitpos) = node i      circuitpos = circuitpos + 1



例题:
输入:边的个数,以及每一条边
输出:化成进制数后最小的序列
FROM:USACO 3.3 fence

代码 :
#include <cstdio>#include <cstring>int d[501][501],ans[1300],s;void find_circuit(int i){    for(int j = 1;j <= 500;j++)        if(d[i][j] > 0)        {            --d[i][j];--d[j][i];            find_circuit(j);        }    ans[++s] = i;}int main(){    freopen("fence.in","r",stdin);    freopen("fence.out","w",stdout);    memset(ans,0,sizeof ans);    int i,m,x,y;    s = -1;    scanf("%d",&m);    for(i = 0;i < m;i++)    {        scanf("%d%d",&x,&y);        d[x][0]++;        d[y][0]++;        d[x][y]++;        d[y][x]++;    }    for(i = 1;i <= 500;i++)        if(d[i][0]%2 == 1)        {            find_circuit(i);            break;        }    if(i == 501)find_circuit(1);    for(i = s;i >= 0;i--)        printf("%d\n",ans[i]);    return 0;}




原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 社保卡丢了看病怎么办 社保卡丢了买药怎么办 常州社保卡丢了怎么办 深圳社保卡掉了怎么办 上海医保卡丢了怎么办 户口转到西安后医保怎么办 上海医保卡掉了怎么办 上海医保本丢了怎么办? 新版医保卡丢了怎么办 武汉社保卡掉了怎么办 职工社保卡丢了怎么办 杭州社保卡丢了怎么办 农村医疗卡丢了怎么办 陕西省医保卡丢了怎么办 小孩社保卡掉了怎么办 社区医保本丢了怎么办 宝宝医保卡掉了怎么办 同煤医疗卡丢了怎么办 杭州医保卡丢了怎么办 新的医保卡丢了怎么办 二代医保卡丢了怎么办 老医保卡丢了怎么办 上海医保卡余额用完了怎么办 身份证丢了医疗报销怎么办 取公积金身份证丢了怎么办 身份证丢了怎么办就诊卡 人在外地怎么办农村社保卡 武汉医保卡丢了怎么办 济宁社保卡丢了怎么办 农村医疗本丢了怎么办 常熟医保卡丢了怎么办 农民社保卡丢了怎么办 常熟社保卡坏了怎么办 社保卡丢失补办期看病怎么办 社保卡补办期间看病怎么办 医保卡冻结了出院结算怎么办 住院医保卡钱不够怎么办 住院押金条丢了怎么办 急用新社保卡要怎么办 看病没带社保卡怎么办 医保卡掉了住院怎么办