zoukankan      html  css  js  c++  java
  • 离散实验——欧拉图的判定和应用

    实验六欧拉图判定和应用

    【实验目的】掌握判断欧拉图的方法。

    【实验内容】编程随机生成n个结点的无向图(有向图)并能进行(半)欧拉图的判定,若是则给出所有欧拉路.

    【要求】对给定n个结点,随机生成邻接矩阵以确定某无向简单图(有向图)并进行欧拉图和半欧拉图的判定,若符合则给出至少一条欧拉回路或欧拉路。

    【实验原理和方法】

    是根据随机生成的图求欧拉(回)路,先要随机生成一个邻接矩阵,然后判定是否是欧拉回路只要根据奇数度结点的个数。再用一个递归函数找出欧拉路。

     

     

     

    (1)用关系矩阵R=表示图。

    (2)对无向图而言,若所有结点的度都是偶数,则该图为欧拉图。

        C语言算法:

      flag=1;

      for(i=1;i<=n && flag;i++)

      {

          sum=0;

          for(j=1;j<=n;j++)

              if(r[i][j]) sum++;

          if(sum%2==0) flag=0;

      }

      如果 flag  该无向图是欧拉图

    (3)对有向图而言,若所有结点的入度等于出度,则该图为欧拉图。

    C语言算法:

    flag=1;

    for(i=1;i<=n && flag;i++)

    {

        sum1=0;

        sum2=0;

        for(j=1;j<=n;j++)

            if(r[i][j]) sum1++;

        for(j=1;j<=n;j++)

            if(r[j][i]) sum2++;

        if(sum1%2==0 || sum2%2==0) flag=0;

    }

    如果 flag  该有向图是欧拉图

    (4)求出欧拉路的方法:欧拉路经过每条边一次且仅一次。可用回溯的方法求得所有欧拉路。

    C语言算法:

    intcount=0,cur=0,r[N][N]; // r[N][N]为图的邻接矩阵,cur为当前结点编号,count为欧拉路的数量。

    int sequence[M];// sequence保留访问点的序列,M为图的边数

    输入图信息;

    void try1(int k) //k表示边的序号

    {

        int i,pre=cur; //j保留前一个点的位置,pre为前一结点的编号

        for (i=0;i<N;i++)

            if (r[cur][i]) //当前第cur点到第i点连通

               {

    //删除当前点与第i点的边,记下第k次到达点i,把第i个点设为当前点

                   r[cur][i]=0;cur=sequence[k]=i; 

                   if (k<M) try1(k+1); //试下一个点

                   else prt1();//经过了所有边,打印一个解

    //上面条件不满足,说明当前点的出度为0,回溯,试下一位置

                   r[pre][i]=1;cur=pre; 

               }

    }

    附上代码:

    有向图:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <time.h>
    int n,a[100][100],m=0,visit[100];
    int cur=0,s[100],vis[100][100];
    void try1(int k)//取欧拉路
    {
        int i;
        if(cur==m+1)
        {
            for(i=0;i<cur;i++)
            {
                if(i==0)
                    printf("%d",s[i]+1);
                else
                    printf("->%d",s[i]+1);
            }
            printf("
    ");
        }
        else
        {
            for(i=0;i<n;i++)
            {
                if(a[k][i]&&!vis[k][i])
                {
                    vis[k][i]=1;
                    vis[i][k]=1;
                    s[cur++]=i;
                    try1(i);
                    cur--;
                    vis[k][i]=0;
                    vis[i][k]=0;
                }
            }
        }
    }
    void dfs(int k)
    {
        int i;
        visit[k]=1;
        for(i=0;i<n;i++)
        {
            if(a[k][i]&&!visit[i])
            {
                dfs(i);
            }
        }
    }
    int fun()//判断连通性
    {
        int i;
        dfs(0);
        for(i=0;i<n;i++)
        {
            if(!visit[i])
                return 0;
        }
        return 1;
    }
    int main(void)
    {
        int i,j;
        memset(vis,0,sizeof(vis));
        memset(visit,0,sizeof(visit));
        srand(time(NULL));
        printf("请输入节点个数n:");
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                if(i==j)
                    a[i][j]=0;
                else if(i>j)
                    a[i][j]=a[j][i];
                else
                    a[i][j]=rand()%2;
                m+=a[i][j];
            }
        }
        m/=2;
        printf("邻接矩阵为:
     ");
        for(i=0;i<n;i++)
        {
            printf(" %d",i+1);
        }
        printf("
    ");
        for(i=0;i<n;i++)
        {
            printf("%d",i+1);
            for(j=0;j<n;j++)
                printf(" %d",a[i][j]);
            printf("
    ");
        }
        if(fun()==0)
        {
            printf("该图不是连通图!
    ");
            return 0;
        }
        printf("该图是连通图!
    ");
        int odd=0;
        for(i=0;i<n;i++)
        {
            int sum=0;
            for(j=0;j<n;j++)
            {
                if(a[i][j])
                    sum++;
            }
            if(sum%2)
                odd++;
        }
        if(odd==0)
        {
            printf("该图没有奇数度节点,具有欧拉回路,是欧拉图。
    ");
            printf("所有的欧拉路为:
    ");
            for(i=0;i<n;i++)
            {
                s[cur++]=i;
                try1(i);
                cur--;
            }
        }
        else if(odd==2)
        {
            printf("该图有两个奇数度节点,具有欧拉路,是半欧拉图。
    ");
            printf("所有的欧拉路为:
    ");
            for(i=0;i<n;i++)
            {
                int sum=0;
                for(j=0;j<n;j++)
                    sum+=a[i][j];
                if(sum%2)//起点或中点
                {
                    s[cur++]=i;
                    try1(i);
                    cur--;
                }
            }
        }
        else
        {
            printf("不是欧拉图,也不是半欧拉图
    ");
        }
        return 0;
    }

    无向图:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <time.h>
    int n,a[100][100],m=0,visit[100];
    int cur=0,s[100],vis[100][100];
    void try1(int k)//取欧拉路
    {
        int i;
        if(cur==m+1)
        {
            for(i=0;i<cur;i++)
            {
                if(i==0)
                    printf("%d",s[i]+1);
                else
                    printf("->%d",s[i]+1);
            }
            printf("
    ");
        }
        else
        {
            for(i=0;i<n;i++)
            {
                if(a[k][i]&&!vis[k][i])
                {
                    vis[k][i]=1;
                    s[cur++]=i;
                    try1(i);
                    cur--;
                    vis[k][i]=0;
                }
            }
        }
    }
    void dfs(int k)
    {
        int i;
        visit[k]=1;
        for(i=0;i<n;i++)
        {
            if(a[k][i]&&!visit[i])
            {
                dfs(i);
            }
        }
    }
    int fun()//判断连通性
    {
        int i,j;
        for(i=0;i<n;i++)
        {
            memset(visit,0,sizeof(visit));
            dfs(i);
            for(j=0;j<n;j++)
            {
                if(!visit[j])
                    break;
            }
            if(j==n)
                return 1;
        }
        return 0;
    }
    int main(void)
    {
        int i,j;
        memset(vis,0,sizeof(vis));
        srand(time(NULL));
        printf("请输入节点个数n:");
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                a[i][j]=rand()%2;
                m+=a[i][j];
            }
        }
        printf("邻接矩阵为:
     ");
        for(i=0;i<n;i++)
        {
            printf(" %d",i+1);
        }
        printf("
    ");
        for(i=0;i<n;i++)
        {
            printf("%d",i+1);
            for(j=0;j<n;j++)
                printf(" %d",a[i][j]);
            printf("
    ");
        }
        if(fun()==0)
        {
            printf("该图不是连通图!
    ");
            return 0;
        }
        printf("该图是连通图!
    ");
        int odd=0,begin=-1,end=-1;
        for(i=0;i<n;i++)
        {
            int sum1=0,sum2=0;
            for(j=0;j<n;j++)
            {
                sum1+=a[i][j];
                sum2+=a[j][i];
            }
            if(sum1!=sum2)
            {
                odd++;
                if(sum1-sum2==1)
                    begin=i;
                if(sum2-sum1==1)
                    end=i;
            }
        }
        if(odd==0)
        {
            printf("该图所有点出度等于入度,具有欧拉回路,是欧拉图。
    ");
            printf("所有的欧拉路为:
    ");
            for(i=0;i<n;i++)
            {
                s[cur++]=i;
                try1(i);
                cur--;
            }
        }
        else if(odd==2&&begin!=-1&&end!=-1)
        {
            printf("该图有两个奇数度节点,具有欧拉路,是半欧拉图。
    ");
            printf("所有的欧拉路为:
    ");
            s[cur++]=begin;
            try1(begin);
        }
        else
        {
            printf("不是欧拉图,也不是半欧拉图
    ");
        }
        return 0;
    }

    过一学期了第一次写离散作业

  • 相关阅读:
    Django 前戏
    SQL基本语句
    如何正确安装Mysql
    JQuery
    解疑答惑—解决脱离标准文档流(恶心的浮动)
    事件
    卷基于快照进行恢复
    centos7下Firewall使用详解
    基于镜像卷启动的虚机快照代码分析
    nova卸载volume源码分析
  • 原文地址:https://www.cnblogs.com/zhaohongjie/p/12950870.html
Copyright © 2011-2022 走看看