UVA 539「卡坦島的殖民者」要求在無向圖中尋找不重複邊的最長路徑(節點可重複訪問)。節點度數 ≤ 3,邊長均為 1。本文介紹基於深度優先搜索(DFS)的暴力回溯解法,利用圖的稀疏性高效求解。
由於邊數較少(≤ 25),可從每條邊作為起點,嘗試所有可能的路徑延伸:
vis[u][v] 表示邊 (u,v) 是否已用。DFS(cur, len):遍歷 cur 的所有鄰居 next,若邊 (cur,next) 未用,標記後遞歸 DFS(next, len+1),回溯時取消標記。ans。#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 30;
int g[MAXN][MAXN];
int vis[MAXN][MAXN];
int n, m, ans;
void DFS(int u, int len) {
for (int v = 0; v < n; ++v) {
if (g[u][v] && !vis[u][v]) {
vis[u][v] = vis[v][u] = 1;
DFS(v, len + 1);
vis[u][v] = vis[v][u] = 0;
}
}
if (len > ans) ans = len;
}
int main() {
while (scanf("%d%d", &n, &m) == 2 && (n || m)) {
memset(g, 0, sizeof(g));
memset(vis, 0, sizeof(vis));
for (int i = 0; i < m; ++i) {
int a, b;
scanf("%d%d", &a, &b);
g[a][b] = g[b][a] = 1;
}
ans = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (g[i][j]) {
vis[i][j] = vis[j][i] = 1;
DFS(i, 1);
vis[i][j] = vis[j][i] = 0;
}
}
}
printf("%d\n", ans);
}
return 0;
}
最壞情況每條邊作為起點,DFS 探索所有歐拉路徑變體。邊數 m ≤ 25,度數 ≤ 3,實際運行極快。時間複雜度約 O(m × 2^m) 但常數極小,完全在限制內。
本題是「圖中最長路徑(邊不重複)」的經典應用。利用題目約束(稀疏圖、低度數),簡單的 DFS 回溯即可高效求解,無需複雜的動態規劃或狀態壓縮。這體現了「根據數據範圍選擇算法」的實用原則。