zoukankan      html  css  js  c++  java
  • 欧拉回路的一点研究与Codeforces 62D Wormhouse

    图G的一个回路,若它恰通过G中每条边一次,则称该回路为欧拉回路。具有欧拉回路的图称为欧拉图。欧拉回路就是从图上的一点出发,经过所有的边一次,最终回到起点的路径。

    首先是求出图中所有欧拉回路的朴素算法。深搜遍历所有的边,直到找到所有的欧拉回路。

    void dfs(int u,int deep)
    {
        ans[deep]=u;//将点u加入到路径中
        if (deep==m)//若遍历了所有的边
        {
            if (u==bg)//终点等于起点,即找到欧拉回路
            {
                for (int i=0; i<=m; i++)
                {
                    cout<<ans[i]<<" ";//输出路径
                }
                cout<<endl;
            }
            return;
        }
        for (int i=1; i<=n; i++)//遍历所有节点
        {
            if (a[u][i])//若当前点u与点i间有边
            {
                a[u][i]=false;a[i][u]=false;//消除此边表示已经遍历过
                dfs(i,deep+1);//寻找下一条边
                a[u][i]=true;a[i][u]=true;//回溯
            }
        }
    }
    

    接下来是寻找并输出字典序最小的欧拉回路的算法。

    bool dfs(int u,int deep)
    {
        ans[deep]=u;//将点u加入到路径中
        if (deep==m)//若遍历了所有的边
        {
            if (u==bg)//终点等于起点,即找到欧拉回路
            {
                for (int i=0; i<=m; i++)
                {
                    cout<<ans[i]<<" ";//输出路径
                }
                cout<<endl;
            }
            return true;//找到字典序最小的欧拉回路
        }
        for (int i=1; i<=n; i++)//遍历所有节点
        {
            if (a[u][i])//若当前点u与点i间有边
            {
                a[u][i]=false;a[i][u]=false;//消除此边表示已经遍历过
                if (dfs(i,deep+1))//寻找下一条边
                {
                    return true;//找到字典序最小的欧拉回路,直接返回true
                }
                a[u][i]=true;a[i][u]=true;//回溯
            }
        }
        return false;//未找到欧拉回路
    }
    

    这种方法一定是对的,但是由于欧拉回路普遍存在很多环,使得这种方法效率很低。


    时间复杂度为O(m)的算法。

    使用深度优先搜索,如果某条边被搜索到,则标记这条边为已选择,并且即使回溯也不能将当前边的状态改回未选择,每次回溯时,记录回溯路径。深度优先搜索结束后,记录的回溯路径就是欧拉回路。

    void dfs(int u)
    {
        for (int i=1;i<=n;i++)
        {
            if (a[u][i])
            {
                a[u][i]=false;
                a[i][u]=false;
                dfs(i);
                ans[++cnt]=i;
            }
        }
    }


    D. Wormhouse
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Arnie the Worm has finished eating an apple house yet again and decided to move. He made up his mind on the plan, the way the rooms are located and how they are joined by corridors. He numbered all the rooms from 1 to n. All the corridors are bidirectional.

    Arnie wants the new house to look just like the previous one. That is, it should have exactly n rooms and, if a corridor from room i to roomj existed in the old house, it should be built in the new one.

    We know that during the house constructing process Arnie starts to eat an apple starting from some room and only stops when he eats his way through all the corridors and returns to the starting room. It is also known that Arnie eats without stopping. That is, until Arnie finishes constructing the house, he is busy every moment of his time gnawing a new corridor. Arnie doesn't move along the already built corridors.

    However, gnawing out corridors in one and the same order any time you change a house is a very difficult activity. That's why Arnie, knowing the order in which the corridors were located in the previous house, wants to gnaw corridors in another order. It is represented as a list of rooms in the order in which they should be visited. The new list should be lexicographically smallest, but it also should be strictly lexicographically greater than the previous one. Help the worm.

    Input

    The first line contains two integers n and m (3 ≤ n ≤ 100, 3 ≤ m ≤ 2000). It is the number of rooms and corridors in Arnie's house correspondingly. The next line contains m + 1 positive integers that do not exceed n. They are the description of Arnie's old path represented as a list of rooms he visited during the gnawing. It is guaranteed that the last number in the list coincides with the first one.

    The first room described in the list is the main entrance, that's why Arnie should begin gnawing from it.

    You may assume that there is no room which is connected to itself and there is at most one corridor between any pair of rooms. However, it is possible to find some isolated rooms which are disconnected from others.

    Output

    Print m + 1 positive integers that do not exceed n. Those numbers are the description of the new path, according to which Arnie should gnaw out his new house. If it is impossible to find new path you should print out No solution. The first number in your answer should be equal to the last one. Also it should be equal to the main entrance.


    题目描述,给定一条欧拉回路,求字典序比它大的欧拉回路中字典序最小的一条。

    将寻找字典序最小欧拉回路的方法二改造,为dfs添加一个新的参数ok,当ok为false时,表示当前的路径的字典序不比给定的路径大,当ok为true时,表示当前路径的字典序必定大于给定的路径。

    #include <iostream>
    
    using namespace std;
    
    bool a[222][222];
    int p[2222];
    int ans[2222];
    int n,m;
    
    bool dfs(int u,int deep,bool ok)
    {
        int v;
        ans[deep]=u;
        if (deep==m) return ok;
        if (ok) v=1;
        else v=p[deep+1];
        for (int i=v;i<=n;i++)
        {
            if (a[u][i])
            {
                a[u][i]=false;
                a[i][u]=false;
                if (i!=p[deep+1])//第deep+1个点大于原路径,字典序必然大于原回路
                {
                    if (dfs(i,deep+1,true)) return true;
                }
                else
                {
                    if (dfs(i,deep+1,ok)) return true;
                }
                a[u][i]=true;
                a[i][u]=true;
            }
        }
        return false;
    }
    
    int main()
    {
        cin>>n>>m;
        for (int i=0;i<=m;i++)
        {
            cin>>p[i];
            if (i>0) a[p[i-1]][p[i]]=a[p[i]][p[i-1]]=true;
        }
        if (dfs(p[0],0,false))
        {
            for (int i=0;i<=m;i++)
            {
                cout<<ans[i]<<" ";
            }
            cout<<endl;
        }
        else
        {
            cout<<"No solution"<<endl;
        }
        return 0;
    }
    


  • 相关阅读:
    java security
    abstract class和interface的区别
    Hibernate是如何延迟加载的
    hibernate 延迟加载
    hibernate 的缓存机制
    Apache POI组件操作Excel,制作报表(四)
    Apache POI组件操作Excel,制作报表(三)
    Apache POI组件操作Excel,制作报表(二)
    Apache POI组件操作Excel,制作报表(一)
    POI中HSSF和XSSF操作Excel
  • 原文地址:https://www.cnblogs.com/cyendra/p/3038384.html
Copyright © 2011-2022 走看看