【圖論】C_mj_騎馬修柵欄(歐拉x路 / dfs)

一、Problem

農民John每年有很多柵欄要修理。他總是騎着馬穿過每一個柵欄並修復它破損的地方。

John是一個懶惰的人,他討厭騎馬,因此從來不兩次經過同一個柵欄。現在你編寫一個程序,讀入柵欄網絡的描述,並計算出一條修柵欄的路徑,使每一個柵欄恰好都經過一次。John能從任何一個頂點(即兩個柵欄的交點)開始騎馬,在任意一個頂點結束。

每個柵欄連接兩個頂點,頂點用1到500標號(雖然有的農場並沒有500個頂點)。一個頂點上可連接任意多(>=1)個柵欄。所有柵欄都是連通的(也就是你可以從任意一個柵欄到達另外的所有柵欄)。

你的程序必須輸出騎馬的路徑(用路上依次經過的頂點號碼錶示)。我們如果把輸出的路徑看成一個500進制的數,那麼當存在多組解的情況下,輸出500進製表示法中最小的一個(也就是輸出第一個較小的數,如果還有多組解,輸出第二個較小的數,等等)。輸入數據保證至少有一個解。

輸入

第1行:一個整數F(1<=F<=1024),表示柵欄的數目。
第2到F+1行:每行兩個整數i,j(1<=i , j<=500)表示這條柵欄連接i與j號頂點。

輸出

輸出應當有F+1行,每行一個整數,依次表示路徑經過的頂點號。注意數據可能有多組解,但是隻有上面題目要求的那一組解是正確的。

輸入示例

9
1 2
2 3
3 4
4 2
4 5
2 5
5 6
5 7
4 6

輸出示例

1
2
3
4
2
5
4
6
5
7

二、Solution

方法一:dfs

沒想到這題和普通的歐拉路問題有啥區別,只是一個點有多條邊罷了…

import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
	static class Solution {
		int[][] mp;
    	int[] ph, in;
    	int n = 500+1000, m, tot;
    
    	void dfs(int s, int N) {
    		for (int i = 1; i <= N; i++) {
    			if (mp[s][i] > 0) {
    				mp[s][i]--;
					mp[i][s]--;
    				dfs(i, N);
    			}
    		}
    		ph[tot++] = s;
    	}
		void init() {
			Scanner sc = new Scanner(new BufferedInputStream(System.in));
			m = sc.nextInt();
			ph = new int[n];
			in = new int[n];
			mp = new int[n][n];
			int N = 0;
			for (int i = 0; i < m; i++) {
				int a = sc.nextInt(), b = sc.nextInt();
				mp[a][b]++; 
				mp[b][a]++;
				in[a]++;    
				in[b]++;
				N = Math.max(N, Math.max(a, b));
			}
			int s = 1;
			for (int i = 1; i <= N; i++) {
				if (in[i] % 2 == 1) {
					s = i;
					break;
				}
			}
			dfs(s, N);
			for (int i = tot-1; i >= 0; i--)
				System.out.println(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)

未知bug:把 N 設置爲全局變量之後,進入 dfs 方法中會被置爲 0 … 無語…

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