【グラフ理論】オイラー図とは?オイラーの道を見つける方法は?

グラフ理論には、オイラーダイアグラム、オイラーパス(1ストローク問題)、オイラー回路などの問題があります。この記事では、その(厳密ではない)定義、いくつかの結論、最後にHierholzerアルゴリズムと対応する例と回答を示します。


(厳密ではない)定義

ための连通的グラフG、あります

  • オイラーパス:すべてのエッジを繰り返さずに通過できるパス。このプロパティは、すべてのエッジを1回のストロークで描画せずに描画するようなものです。欧拉路径そのため、関連する問題のいくつかが呼び出され一笔画问题ます。
  • オイラー回路:すべてのエッジを繰り返すことなく通過し、開始点に戻ることができるパス。それはそれを見ることができます欧拉回路あまりにも欧拉路径
  • セミオイラー図:図に存在する図欧拉路径
  • オイラーダイアグラム:ダイアグラムに存在するダイアグラム欧拉回路それはそれを見ることができます欧拉图あまりにも半欧拉图

オイラー経路とオイラー回路の図と結論

接続された条件无向图は、(半)オイラー線図です。

  1. すべての頂点の次数が偶数の場合、任意の頂点から見つけることができます欧拉回路逆も同様です。つまり、任意の頂点から開始点を見つけることができる場合、欧拉回路すべての頂点の次数は均一です。
  2. 次数が奇数の頂点が2つしかない場合、それらは見つけることができます欧拉路径(パスは2つのポイントのいずれかの頂点から始まり、もう一方の頂点で終わります)。反対も当てはまります。

接続された条件有向图は、(半)オイラー線図です。

  1. すべての頂点の入次数が出次数と等しい場合、任意の頂点から開始点を見つけることができます欧拉回路反対も当てはまります。
  2. 頂点が2つしかない場合、インディグリーはアウトディグリーと等しくなく、頂点の1つのインディグリーはアウトディグリーより1大きく、V 1 V_1として記録されます。V1、他の頂点のインディグリーは、アウトディグリーより1小さく、V 2 V_2として示されます。V2、あなただけが見つけることができます欧拉路径(頂点V 2 V_2からのパスV2頂点V 1 V_1への出発V1終わり)。反対も当てはまります。

コネクテッド混合图は、(半)オイラーグラフの条件です:(混合图有向エッジと無向エッジの両方を持つグラフを指します。)

  1. 各無向エッジを方向付けて、各頂点のインディグリーがアウトディグリーと等しくなるようにして、有向グラフに変換できるようにする戦略を見つけます。这个有待考究

Hierholzerアルゴリズム

問題の簡単な説明:(半)オイラーダイアグラムが与えられたら、オイラーパスを見つけます。

Hierholzerアルゴリズムのアイデア:与えられたグラフに)が必要な場合、開始点欧拉路径(回路から合理的始まり(後で言うことは妥当です)、グラフ全体の深さ優先のトラバーサル、トラバースされた頂点は、最初に遭遇するまで再度トラバースしてはなりません没有可遍历的邻居頂点は、この頂点は、(実際には削除され、エッジをマーキングすることによってアクセスすることができなくなったアクセスそれなしで)「削除」次遭遇上面にストリップオイラー経路の端部である没有可遍历的邻居頂点、これはこのオイラーパスの最後から2番目の頂点である必要があります。次に、この頂点を「削除」してからもう一度トラバースし、すべて没有可遍历的邻居の頂点が見つかるまで、このオイラーパス上のすべての頂点を見つけます。
質問1:一部の人々は、なぜHierholzerアルゴリズムがオイラーパスを取得できなければならないのか疑問に思うかもしれません。発生したすべての没有可遍历的邻居頂点オイラーのパスの終点であるのはなぜですか?下面以有向图作为说明,无向图同理。これは実際には、頂点の度数と度数に関係します。
トラバーサルが特定の頂点から始まる場合、トラバースするエッジがなくなるまで、トラバースしたエッジをトラバースすることはできません。別のアウトディグリーがインディグリー頂点VVと等しい場合VのときVVにとどまることは不可能ですV、なぜならVVV out度はin度と同じです。何度入力するかには、対応するout側が必要です
したがって、最初に遭遇する没有可遍历的邻居頂点2つのタイプのみであり、1つはその次数が1つが次数より大きいこと、もう1つはその次数とその次数が等しいことですが、それは開始点です(つまり、開始点であり、終わりです、1周分余裕があります)。上記のいくつかの結論(グラフの結論とオイラーパス、オイラー回路)によると、これらの2つのポイントは特定のオイラーパスの終点であるため没有可遍历的邻居、頂点に遭遇しとき、安心して太字にすることができますオイラーのパスの最後でなければならないため、この頂点が記録されます。
質問2:遭遇した2番目の没有可遍历的邻居頂点がオイラーのパスの最後から2番目のポイントである理由を疑問に思う方もいるかもしれません最初の没有可遍历的邻居頂点と対応するエッジ「削除」した後(実際には削除する必要はなく、訪問済みであることをマークするだけです)、隣接する頂点の度数と度数が発生すると想像できます。変更してドラフトペーパーを描くと、その周囲の頂点が、次数が次数に等しい頂点、または次数が1次よりも大きい頂点になり、すべてオイラーのパスの終点に一致することがわかります。条件、そして私たちは深さ優先のトラバーサルであるため、前のレイヤーに再帰的に戻った後、それはこれらの隣接する頂点の間にある必要があります。したがって、このときに遭遇する2番目の没有可遍历的邻居頂点最後から2番目のオイラーパスでなければなりませんポイント。

Hierholzerアルゴリズムプロセス

  • 1つ合理的点を開始点として選択し、隣接するすべてのエッジをトラバースします。(私は何を言うつもりです合理的点
  • 最初に深さを検索し、隣接する頂点にアクセスします。通過する側にアクセスできなくなります。
  • 現在の頂点に隣接するエッジがない場合、頂点は配列の最後に配置されます。
  • 最後に、配列は逆の順序で出力されます。これは、開始点から始まるオイラー回路です。

Hierholzerアルゴリズム関数:個人的にHierholzer 算法は、与えられたグラフに)がなければならないときに、無知な深さ優先検索に欧拉路径(回路よると、逆の順序Hierholzer 算法が確実に得られるという証拠だと私感じています欧拉路径(回路)あなたがいるかどうかそれを得る欧拉路径かどうか欧拉环路、それはあなたの写真があるかどうかに依存し欧拉图、まだ半欧拉图。絵がいる場合欧拉图欧拉环路、あなたは何である取得画像がある場合は、半欧拉图あなたが得るものyesです欧拉路径Hierholzerアルゴリズムがオイラーパスを取得できるのはなぜですか?その原理は何ですか?こちらをご覧ください
注:画像がでない欧拉图かどうかは半欧拉图Hierholzer 算法それを使用して得られた結果が間違っている必要があります。したがって、急いHierholzer 算法採用する前に、グラフと上記のオイラーパスとオイラー回路の結論に従って、グラフが最後にあるかどうか判断する必要があります。(半)欧拉图そうである場合、このアルゴリズムを使用してそれを見つけることができます欧拉路径(回路)

合理的開始点は何ですか:上記合理的点の開始点としての選択、それで何点合理的ですか?ここでは前述のグラフとオイラーパスおよびオイラー回路との関係を確認する必要があります。無向グラフを例とります(有向グラフについて同様です)。

  • 写真がオイラー線図の場合、任意の点から始点を見つけることができますが、現時点では、任意の点から欧拉回路始めてオイラー回路を見つけることができるので、どの点でも合理的;
  • グラフが準オイラーグラフである場合、次数が奇数の頂点は2つしかなく、それらを見つけることができます欧拉路径(パスはこれら2つのポイントのいずれかで始まり、もう一方のポイントで終わります)。出発するとすぐにオイラーの進路を見つけることができるので、これらの2点だけがになり合理的ます。

:Hierholzerアルゴリズムを習得するために、ここに例[リートコード] 332を
示します。旅程再配置(C ++)の例の質問に対する答え

// 思路:
// Hierholzer算法。个人觉得Hierholzer算法就是证明了一点:当存在欧拉路径时,从合理的起始点无脑dfs遍历,得到的路径一定是欧拉路径。
// 因为题目规定了一定有欧拉路径,并且起点一定是JFK(所以这个起始点一定是合理的),所以根据Hierholzer算法,可以无脑dfs。

class Solution {
    
    
public:
    // 这里用map,内部自动按照string升序排列了,所以先找到的一定是自然排序最小的路径
    typedef unordered_map<string, map<string, int>> adjacent;
    vector<string> min_path;
    bool dfs(adjacent &adj, string airport){
    
    
        // 无脑dfs遍历邻居,同时遍历过的边标记已遍历
        for(auto &[next, number] : adj[airport]){
    
    
            if(0 >= number)
                continue;
            --number;
            dfs(adj, next);
        }
        // 终点是没有相邻边的点
        // 当删除终点后,终点前的点也没有相邻边了,变成新的终点
        // 运行到这里,当前airport一定没有可遍历的相邻边了,则它是此时的终点
        min_path.push_back(airport);
        return true;
    }
    vector<string> findItinerary(vector<vector<string>>& tickets) {
    
    

        // 初始化邻接表,因为存在多张相同机票的情况,所以邻接表中还记录了从from到to的机票数
        adjacent adj;
        for(auto & t : tickets){
    
    
            if(adj.find(t[0]) == adj.end())
                adj[t[0]] = map<string, int>();
            if(adj[t[0]].find(t[1]) == adj[t[0]].end())
                adj[t[0]][t[1]] = 0;
            adj[t[0]][t[1]]++;
        }
        // Hierholzer算法
        dfs(adj, "JFK");

        // Hierholzer算法得到结果为终点到起点的路径,需要反转才是题目所要求的结果
        std::reverse(min_path.begin(), min_path.end());
        return min_path;
    }
};

関連/参照リンク

「グラフ理論」エントリとHierholzerアルゴリズム
オイラー/パス[概要]
オイラーパスなし、マップするループテンプレート(Hierholzerアルゴリズム)

おすすめ

転載: blog.csdn.net/a435262767/article/details/105253850