zoukankan      html  css  js  c++  java
  • 欧拉回路(fleuru算法实现)

    书上的欧拉回路定义不在重复,欧拉回路定义

    弗洛莱走边的方法也不再细讲,弗洛莱算法描述

    这里只说怎么进行代码实现。



    /*
    无向图的欧拉回路 
    邻接矩阵存图
    
    原理:
    dfs走边,当走不动时就将其放入栈中,最后将顶点从栈中取出的顺序就是欧拉路径。
    如果走错边则必定会堵,那么就会将堵的放入栈中,从栈中取出的话就看作是最后走的割边,符合弗洛来算法;
    如果走的边正确了,那么放入栈中的边取出时也与弗洛莱算法的顺序一致。
    
    代码实现:
    dfs 无路可走则放入栈中,最后栈就是一个欧拉路径
    */
    #include<stdio.h>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<math.h>
    using namespace std;
    const int maxn=1e3+10;
    int ans[maxn];//存放点的顺序
    int book[maxn];//表示每个点的度数
    int map[maxn][maxn];
    int top;
    void dfs(int);
    int n,m;
    void fleury(int beg)
    {
        top=0;
        dfs(beg);
    }
    void dfs(int beg)
    {
        for(int i=1;i<=n;i++)
        {
            if(map[beg][i])
            {
                map[beg][i]--;
                map[i][beg]--;
                dfs(i);
            }
        }
        ans[top++]=beg;//放入栈中
    }
    void Print_road()//输出路径
    {
        for(int i=top-1;i>=0;i--)
        {
            printf("%d",ans[i]);
            if(i)
                printf("-->");
        }
        puts("");
    }
    int main()
    {
        int beg;
        while(~scanf("%d %d",&n,&m))//共有n个点,m个边   //欧拉回路所有边只走一次
        {
                memset(book,0,sizeof(book));
                memset(map,0,sizeof(map));
    
                for(int i=0;i<m;i++)
                {
                    int u,v;
                    scanf("%d %d",&u,&v);
                    book[u]++;
                    book[v]++;
                    map[u][v]=map[v][u]=1;
                }//构建数组链表
                beg=1;
                int cnt=0;
                for(int i=1;i<=n;i++)
                {
                    if(book[i]&1)
                    {
                        cnt++;
                        beg=i;
                    }
                }
                if(!cnt||cnt==2)//找出beg
                {
                    fleury(beg);
                    Print_road();
                }
                else
                {
                    printf("不存在欧拉回路
    ");
                    continue;
                }
        }
    } 


    /*
    
    fleury 有向边
    用了邻接表实现
    */
    
    #include<stdio.h>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<math.h>
    using namespace std;
    const int maxn=1e3+10;
    struct Node
    {
        int v;
        int next,index,flag;
    } node[maxn];
    int head[maxn];//存放每个u节点的第一个指向
    int ans[maxn];//存放点的顺序
    int rbook[maxn],cbook[maxn];//表示每个点的度数
    int top;
    void dfs(int);
    void fleury(int beg)
    {
        top=0;
        dfs(beg);
    }
    void dfs(int beg)
    {
        int to;
        to=head[beg];
        while(to!=-1)
        {
            if(node[to].flag)
            {
                node[to].flag=0;
                dfs(node[to].v);
            }
            to=node[to].next;
        }
        ans[top++]=beg;
    }
    void Print_road()//输出路径
    {
        for(int i=top-1;i>=0;i--)
        {
            printf("%d",ans[i]);
            if(i)
                printf("-->");
        }
        puts("");
    }
    int main()
    {
        int n,m,beg;
        while(~scanf("%d %d",&n,&m))//共有n个点,m个边   //欧拉回路所有边只走一次
        {
                memset(rbook,0,sizeof(rbook));
                memset(cbook,0,sizeof(cbook));
                memset(head,-1,sizeof(head));
    
                for(int i=0;i<m;i++)
                {
                    int u,v;
                    scanf("%d %d",&u,&v);
                    cbook[u]++;
                    rbook[v]++;
                    node[i].v=v;
                    node[i].flag=1;
                    node[i].index=i;
                    node[i].next=head[u];
                    head[u]=i;
                }//构建数组链表
                beg=1;
                int cnt=0;
                for(int i=1;i<=n;i++)
                {
                    if(rbook[i]!=cbook[i])//计算出度不等于入读的个数
                    {
                        cnt++;
                        if(cbook[i]>rbook[i])//因为总的出度与总的入度个数是相同的,所有必有一大一小
                            beg=i;
                    }
                }
                if(!cnt||cnt==2)//找出beg
                {
                    fleury(beg);
                    Print_road();
                }
                else
                {
                    printf("不存在欧拉回路
    ");
                    continue;
                }
        }
    }
  • 相关阅读:
    Try out the latest C++ compiler toolset without waiting for the next update of Visual Studio
    MAC OS X 系统怎么样?
    java多线程总结
    软件开发的一些概念
    原生JS投票特效
    PHP+MySql例子
    CSS控制文本超出指定宽度显示省略号和文本不换行
    android图片拖动缩放
    jQuery带控制按钮向上和向下滚动文本列表
    HTML5 语义元素
  • 原文地址:https://www.cnblogs.com/dchnzlh/p/9780059.html
Copyright © 2011-2022 走看看