Euler circuit (detailed explanation)

  • Euler path and Euler circuit:
    Euler path : For graph G, if there is a path that contains all the edges of G, then the path is called Euler path, also called Euler path.
    Euler circuit : If the Euler path is a circuit, it is called a Euler circuit.
    Euler diagram : A diagram containing an Euler circuit is an Euler diagram .

  • For directed graph G and undirected graph H: the necessary and sufficient conditions
    for the existence of Euler path and Euler loop in graph G are: Euler path: the number of all singular points in the graph is 0 or 2. Euler loop: Fig. The degrees of all points in are even numbers.

    The necessary and sufficient conditions for the existence of Euler path and Euler circuit in graph H are respectively:
    Euler path: the in-degree of all points is equal to the out-degree or there is a point where the out-degree is 1 greater than the in-degree (starting point), and the in-degree of a point is greater than the out-degree. 1 (end point), the in-degree of other points is equal to the out-degree.
    Euler circuit: the in-degree of all points is equal to the out-degree.

  • question

    A cycle that passes through each edge of a graph once and only once is called an Euler cycle.

    The problem now is, given an undirected graph or a directed graph, determine whether there is a Euler loop, and if so, find an Euler loop.

    basic algorithm

    First consider the case of undirected graph.

    In the following discussion, it is assumed that there are no isolated points (points with degree 0) in the graph. Because removing isolated points from the graph does not affect the existence of the Euler circuit.

    There is a conclusion: there is an Euler cycle in the undirected graph G if and only if the graph G is connected and the degree of all vertices is even.

    prove:

    Necessity: For an Euler circuit C, since C passes through all the edges of the graph G, C passes through all the points of the graph G, so the graph G is connected.

    Because C is a cycle, the number of edges connected to each point in C is an even number. Since each edge passes through and is passed only once, the degree of each point in the graph G is an even number.

    Adequacy:

    That is to say, it is proved that if the graph G is connected and the degree of all vertices is even, then G has an Euler circuit.

    Proof by induction.

    Assume that the conclusion is true for all subgraphs of G, and now the proof is true for G.

    Since the graph G is connected and all vertices have even degrees, there must be a cycle.

    Because starting from an arbitrary point, every time you choose an untraveled edge, you will definitely reach a point that you have already traveled, and then you will find a loop.

    Suppose C is a cycle of graph G. Delete C from the graph G to obtain the graph G′. Then for each connected block of G′, the degree of all points must be even, so there is an Euler cycle.

    For two loops with common points, we can merge them to get a new loop. Because for a loop, you can start from any point on the loop and finish the loop and then return to yourself, then you only need to start from the common point, finish the first loop, and then finish the second loop to get their combined loop.

    Therefore, the Euler circuit of G can be obtained by merging the Euler circuits of each connected block of C and G′ in sequence.

    Certification completed.

    At the same time, the algorithm for finding the Euler circuit of the graph G can be obtained:

  • Find a loop C arbitrarily from the graph G;
  • Delete the edge belonging to C in the graph G to obtain G′;
  • Recursively search for Euler circuits in each connected block of G′;
  • Merge the Euler circuit of each connected block of G' with C to obtain the Euler circuit of graph G.
  • Question link   Euler circuit - Question - Universal Online Judge
  • AC code:
  • #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 100100, M = 400100;
    
    int h[N],e[M],ne[M],idx;
    int ans[N*2],cnt;
    bool used[M];
    int din[N],dout[N];
    int n,m,ver;
    
    void add(int a,int b){
        e[idx] = b,ne[idx] = h[a],h[a] = idx++;
    }
    
    void dfs(int u){
        for(int &i = h[u]; ~i; ){
            if(used[i]){  //如果这条边用过了
                i = ne[i];   //删除这条边
                continue;
            }
    
            used[i] = true;  //标记这条边已使用
            if(ver == 1) used[i^1] = true;   //如果是无向图,那么这条边的反向边也要标记使用过了
    
            int t;
            if(ver == 1){
                t = i/2 + 1;
                if(i&1) t = -t;  //(0,1) (2,3) (4,5) 奇数编号是返回的边
    
            }else t = i+1;
    
            int j = e[i];
            i = ne[i];
            dfs(j);
            ans[cnt++] = t;
        }
    }
    int main()
    {
        scanf("%d%d%d",&ver,&n,&m);
        memset(h,-1,sizeof h);
    
        for(int i = 0; i<m; i++){
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b);
            if(ver == 1) add(b,a);  //无向边
            din[b]++, dout[a]++;   
        }
    
        if(ver == 1){
            for(int i = 1; i<=n; i++){
                if(din[i]+dout[i] &1){
                    //无向图含欧拉回路的充要条件是每个点的度都为偶数
                    puts("NO");
                    return 0;
                }
            }
        }else{
            for(int i = 1; i<=n; i++){
                if(din[i] != dout[i]){
                    //有向图含欧拉回路的充要条件是每个点的入度等于出度
                    puts("NO");
                    return 0;
                }
            }
        }
    
        for(int i = 1; i<=n; i++){
            if(~h[i]) {
                dfs(i);
                break;
            }
        }
    
        if(cnt < m){
            puts("NO");
            return 0;
        }
    
        puts("YES");
        for(int i = cnt-1; i>=0; --i){
            cout<<ans[i]<<" ";
        }
        return 0;
    }
    
    

Guess you like

Origin blog.csdn.net/weixin_74088105/article/details/132419121