feature

定理1
无向图G 为欧拉图,当且仅当G 为连通图且所有顶点的度为偶数。

推论1
无向图G 为半欧拉图,当且仅当G 为连通图且除了两个顶点的度为奇数之外,其它所有顶点的度为偶数

 

定理2
有向图G 为欧拉图,当且仅当G 的基图3连通(即有向图弱连通/连通),且所有顶点的入度等于出度。

推论2
有向图G 为半欧拉图,当且仅当G 的基图连通,且存在恰好一个顶点u 的入度比出度大1、恰好一个v 的入度比出度小1,其它所有顶点的入度等于出度。

 

 

求欧拉回路的思路:

  循环的找到出发点。从某个节点开始,然后查出一个从这个出发回到这个点的环路径。这种方法不保证每个边都被遍历。如果有某个点的边没有被遍历就让这个点为起点,这条边为起始边,把它和当前的环衔接上。这样直至所有的边都被遍历。这样,整个图就被连接到一起了。

  具体步骤:

  1。如果此时与该点无相连的点,那么就加入路径中

  2。如果该点有相连的点,那么就列一张表,遍历这些点,直到没有相连的点。

  3。处理当前的点,删除走过的这条边,并在其相邻的点上进行同样的操作,并把删除的点加入到路径中去。

  4。这个其实是个递归过程。

 

代码:

#include <string.h>
#include <iostream>

 

using namespace std;

 

#define VN 100
//#define EN 100

 

bool g[VN][VN];
int N,M,degree[VN];

int stack[VN],top=-1;

 

void solve(int i)
{
    if(degree[i]==0)
        stack[++top]=i;
    else
    {
        int j;
        for(j=1; j<=N; j++)
        {
            if(g[i][j])
            {
                g[i][j]=false;
                degree[i]--;

                g[j][i]=false;
                degree[j]--;

                solve(j);
            }
        }
        stack[++top]=i;
    }
}

int main()
{
    cin>>N>>M;
    int i,j;
    memset(g,false,sizeof(g));
    while(M--)
    {
        cin>>i>>j;
        g[i][j]=true;
        degree[i]++;

        degree[j]++;
        g[j][i]=true;
    }
    solve(1);

    //如果要保持搜索时候边的优先级,则逆向输出
    while(top>=0)
    {
        cout<<stack[top]<<" ";
        top--;
    }
    return 0;
}

 /*
P299
9 14
1 8
2 1
2 3
3 4
4 5
4 9
5 6
6 4
6 7
7 8
8 2
8 9
9 2
9 6
1 2 3 4 5 6 4 9 2 8 7 6 9 8 1
*/

 

//*********************************************************************

 

#include <string.h>
#include <iostream>

using namespace std;

#define VN 100
#define EN 100

bool g[VN][VN];
int N,M,degree[VN];

typedef struct edge
{
    int x,y;
} edge;

edge stack[EN];
int top=-1;

void solve(int i)
{
    int j;
    for(j=1; j<=N; j++)
    {
        if(g[i][j])
        {
            g[i][j]=false;
            degree[i]--;

            g[j][i]=false;
            degree[j]--;

            solve(j);
            ++top;
            stack[top].x=i;
            stack[top].y=j;
        }
    }
}

int main()
{
    cin>>N>>M;
    int i,j;
    memset(g,false,sizeof(g));
    while(M--)
    {
        cin>>i>>j;
        g[i][j]=true;
        degree[i]++;

        degree[j]++;
        g[j][i]=true;

    }
    int start=1;
    solve(start);
    cout<<"ans:"<<endl;

    //如果要保持搜索时候边的优先级,则逆向输出
    while(top>=0)
    {
        cout<<stack[top].x<<" "<<stack[top].y<<endl;;
        top--;
    }
    return 0;
}

 

分类:

技术点:

相关文章:

  • 2019-01-29
  • 2021-08-07
  • 2021-08-07
  • 2019-10-21
  • 2021-08-07
  • 2021-08-07
  • 2021-09-12
  • 2021-08-07
猜你喜欢
  • 2021-10-05
  • 2021-04-23
  • 2021-08-07
  • 2021-08-07
相关资源
相似解决方案