【圖論】C_mj_一筆畫問題(歐拉x路 / dfs)

一、Problem

如果一個圖存在一筆畫,則一筆畫的路徑叫做歐拉路,如果最後又回到起點,那這個路徑叫做歐拉回路。

根據一筆畫的兩個定理,如果尋找歐拉回路,對任意一個點執行深度優先遍歷;找歐拉路,則對一個奇點執行 dfs,時間複雜度爲 O(m+n)O(m+n),m爲邊數,n是點數。

Input

第一行 n,m,有 n 個點,m 條邊,以下 m 行描述每條邊連接的兩點。

Output

歐拉路或歐拉回路, 輸出一條路徑即可。

輸入
5 5
1 2
2 3
3 4
4 5
5 1

輸出
1 5 4 3 2 1

二、Solution

方法一:dfs

  • 歐拉路:圖是連通的,有且只有 2 個奇度頂點。
  • 歐拉回路:圖是連通的,有 0 個奇度頂點。
  • 如果奇度頂點不是 0/2 那麼無解…

😂 找到奇度頂點 s:

  • 如果沒有奇度頂點,那麼隨便一個頂點開始都可。
  • 否則, 從 s 觸發,遍歷整張圖,遍歷的時候記得把邊抹掉,不然會重複遍歷。
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
    static class Solution {
        int[][] mp;
        int[] ph, in;
        int n, m, tot;
        void dfs(int s) {
            for (int i = 1; i <= n; i++) {
                if (mp[s][i] == 1) {
                    mp[s][i] = mp[i][s] = 0;
                    dfs(i);
                }
            }
            ph[tot++] = s;
        }
        void init() {
            Scanner sc = new Scanner(new BufferedInputStream(System.in));
            n = sc.nextInt(); m = sc.nextInt();
            ph = new int[n+5];
            in = new int[n+1];
            mp = new int[n+1][n+1];
            for (int i = 0; i < m; i++) {
                int a = sc.nextInt(), b = sc.nextInt();
                mp[a][b] = mp[b][a] = 1;
                in[a]++; in[b]++;
            }
            int s = 1;
            for (int i = 1; i <= n; i++) {
                if (in[i] % 2 == 1) {
                    s = i;
                    break;
                }
            }
            dfs(s);
            for (int i = 0; i <= n; i++) {
                System.out.print(ph[i] + " ");
            }
        }
    }
    public static void main(String[] args) throws IOException {  
        Solution s = new Solution();
        s.init();
    }
}

複雜度分析

  • 時間複雜度:O(E+V)O(E+V)
  • 空間複雜度:O(E+V)O(E+V)

稍微變形:https://blog.csdn.net/C20181220_xiang_m_y/article/details/52776779

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章