無向圖的歐拉迴路線性時間演算法

來源:互聯網
上載者:User
// 無向圖的歐拉迴路線性時間演算法
// by rappizit@yahoo.com.cn
// 2007-11-02

#include <vector>
#include <list>
#include <stack>
#include <algorithm>
#include <iostream>
using namespace std;

#define pause system("pause")
typedef vector <int> vi;
typedef list <int> li;
typedef vector <li> vli;

vi EulerCircle (vli G)
{
    int n = G.size ();
    int edge = 0;
    for (int i = 0; i < n; i ++)
        {
        int degree = G [i].size ();
        if (degree % 2 || !degree)
            {
            return vi (0);
            }
        edge += degree;
        }
    vi path (edge / 2 + 1);
    stack <int> s;
    int p = 0, i = 0;
    do    {
        if (G [i].empty ())
            {
            do    {
                s.pop ();
                path [p ++] = i;
                } while (!s.empty () && (i = s.top (), G [i].empty ()));
            }
        else    {
            int t = *(G [i].begin ());
            G [i].erase (G [i].begin ());
            G [t].erase (find (G [t].begin (), G [t].end (), i));
            // 使用帶有十字連結的雙向鄰接表可以常數時間地刪除邊 e(t, i)?!
            s.push (t);
            i = t;
            }
        } while (!s.empty ());
    return path;
}

void main ()
{
    int n, m;
    cin >> n >> m;
    vli G (n);
    while (m --)
        {
        int u, v;
        cin >> u >> v;
        G [u].push_back (v);    // 這裡為了迎合書上的例子,每條無向邊分兩次輸入
        }
    vi path = EulerCircle (G);
    if (path.size ())
        {
        for (int i = 0; i < path.size (); i ++)
            {
            cout << path [i] << " ";
            }
        cout << endl;
        }
}

無向圖的歐拉迴路
採用鄰接表格儲存體,vector <list <int>> 類型。
1.如果某點的度數為奇數或零,則沒有歐拉迴路,返回空的 vector。
2.否則,從標號為 i = 0 的點開始。
3.如果 i 沒有鄰接點,那麼堆棧中所有沒有鄰接點的點彈出到 vector path 中,如果堆棧非空則 i 賦值為棧頂元素。
  否則取 i 的第一個鄰接點 t ,刪除它們的邊(要在 G 中的兩處都刪除)。將 t 壓棧。i 賦值為 t 。
4.如果堆棧為空白,返回 path,否則轉 3。
演算法時間複雜度為 O (E)。

測試資料:
7 20
0 1
0 2
0 5
0 6
1 0
1 2
2 0
2 3
2 4
2 1
3 4
3 2
4 6
4 5
4 3
4 2
5 4
5 0
6 4
6 0

測試結果:
0 6 4 2 3 4 5 0 2 1 0

過程圖示:

First, the program adds the edge 0-1 to the tour and removes it from the adjacency lists (in two places) (top left, lists at left). Second, it adds 1-2 to the tour in the same way (left, second from top). Next, it winds up back at 0 but continues to do another cycle 0-5-4-6-0, winding up back at 0 with no more edges incident upon 0 (right, second from top). Then it pops the isolated vertices 0 and 6 from the stack until 4 is at the top and starts a tour from 4 (right, third from from top), which takes it to 3, 2, and back to 4, where upon it pops all the now-isolated vertices 4, 2, 3, and so forth. The sequence of vertices popped from the stack defines the Euler tour 0-6-4-2-3-4-5-0-2-1-0 of the whole graph.

參考來源:
Algorithms In Java, Part 5 Graph Algorithms , Chapter 17.7 / Java 演算法(第 3 版,第 2 卷)——圖演算法,章節 17.7

PS:但是我是用 C++ 實現的^_^

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.