經典的「分油問題」(又稱水壺問題)是圖論在程式設計教學中的常見案例。給定三個容量不同的油瓶與一個目標容量,需透過倒油操作達到目標狀態。本質上是一個狀態空間搜尋問題,每個狀態代表三瓶油的當前體積,合法的倒油動作構成狀態間的邊。
// 狀態結構
typedef struct {
int v[3]; // 三瓶油體積
int prev; // 前驅節點索引,用於回溯路徑
int action; // 記錄操作:從哪倒向哪
} State;
State states[MAX_STATES];
bool visited[MAX_CAP+1][MAX_CAP+1][MAX_CAP+1]; // 三維訪問標記
// BFS 主循環
while (front < rear) {
State cur = q[front++];
if (is_target(cur)) { /* 找到目標,回溯輸出路徑 */ break; }
// 枚舉 6 種倒油方向 (3*2)
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) if (i != j) {
State nxt = pour(cur, i, j); // 執行倒油
if (!visited[nxt.v[0]][nxt.v[1]][nxt.v[2]]) {
visited[...] = true;
nxt.prev = front - 1;
q[rear++] = nxt;
}
}
}
}
分油問題是圖論建模與 BFS 算法的優秀練習。雖然題目要求「鄰接矩陣」,但實際工程中應根據資料規模選擇鄰接表或隱式圖搜尋。掌握狀態壓縮、訪問標記、路徑回溯三大核心技巧,即可輕鬆解決此類狀態空間搜尋問題。