一、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();
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,
未知bug:把 N 設置爲全局變量之後,進入 dfs 方法中會被置爲 0 … 無語…