题目描述 这次烹饪比赛有4道菜品,小花需要一道一道地制作,因为大赛规定要完成一道菜品后才能完成下一道菜品。每道菜品都有一个配方。其中第i道菜的配方共包含s[i]个步骤,完成每个步骤需要一些时间,可能不等,每个步骤的制作顺序可以随意调整。小花只有两个灶台可以同时使用,菜品的每个步骤都只能在其中一个灶台上制作,一个灶台同一时间内只能进行一个步骤的制作。现在她想知道,在任意顺序制作的情况下,最短需要多长时间才能完成所有的菜品。 输入 本题包含 5 行数据:第 1 行,为四个正整数s[1],s[2],s[3],s[4] 第 2 行,为A[1],A[2]...A[s[1]]共s[1]个数,表示第一个菜品每个步骤所消耗的时间。 第 3 行,为B[1],B[2],...B[s[2]]共s[2]个数。 第 4 行,为C[1],C[2],...C[s[3]]共s[3]个数。 第 5 行,为D[1],D[2],...D[s[4]]共s[4]个数,意思均同上。 输出 一行一个整数,表示完成 4 道菜品的最短时间。 输入样例 1 1 2 1 3 5 4 3 6 2 4 3 输出样例 1 20 数据范围 对于100%的数据: 1≤s[1],s[2],s[3],s[4]≤20。 1≤A[1],A[2]...A[s[1]],B[1],B[2],...B[s[2]],C[1],C[2],...C[s[3]],D[1],D[2],...D[s[4]]≤60。 请你利用深度优先搜索的方法用C++完成本题
时间: 2025-05-28 09:42:07 浏览: 13
### 基于深度优先搜索的烹饪比赛最短时间计算
要通过 C++ 实现基于深度优先搜索 (DFS) 的算法来解决烹饪比赛中完成 4 道菜品所需最短时间的问题,可以按照以下方法设计程序结构。
#### 背景说明
假设每道菜有不同的制作时间和依赖关系(某些菜可能需要其他菜完成后才能开始)。此问题可以通过图论中的拓扑排序和 DFS 来求解。具体来说,DFS 可用于遍历所有可能的时间安排组合,并记录最小总耗时[^1]。
以下是完整的解决方案:
---
#### 数据结构定义
为了表示菜品之间的依赖关系以及它们各自的制作时间,可以用邻接表存储有向无环图 (DAG),其中节点代表菜品,边代表依赖关系。同时维护一个数组 `time[]` 表示各菜品的基础制作时间。
```cpp
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
// 定义全局变量
int minTime = INT_MAX; // 记录当前找到的最短时间
vector<int> bestOrder; // 存储最优顺序
```
---
#### 深度优先搜索函数
编写递归形式的 DFS 函数,在每次调用中尝试分配一道新菜品给厨师并更新剩余可用时间。如果发现某条路径无法满足条件,则立即回溯。
```cpp
void dfs(int current, int totalTime, vector<bool>& visited, const vector<vector<int>>& adjList, const vector<int>& timeArray) {
if (current >= adjList.size()) { // 如果已经处理完所有菜品
if (totalTime < minTime) { // 更新最短时间
minTime = totalTime;
}
return;
}
for (size_t i = 0; i < adjList.size(); ++i) {
if (!visited[i]) { // 尝试选择未访问过的菜品
bool canCook = true;
for (auto pre : adjList[i]) { // 检查前置条件是否已满足
if (!visited[pre]) {
canCook = false;
break;
}
}
if (canCook) { // 若可选该菜品
visited[i] = true; // 标记为已访问
int newTotalTime = totalTime + timeArray[i]; // 更新总时间
// 继续深搜下一层级
dfs(current + 1, max(newTotalTime, totalTime), visited, adjList, timeArray);
visited[i] = false; // 回溯操作
}
}
}
}
```
---
#### 主函数逻辑
初始化输入数据,构建 DAG 和基础时间列表,随后启动 DFS 进程寻找最佳方案。
```cpp
int main() {
int n; // 菜品数量
cin >> n;
vector<int> timeArray(n); // 各菜品的基础制作时间
for (int& t : timeArray) cin >> t;
vector<vector<int>> adjList(n); // 构建邻接表
int m; // 边的数量
cin >> m;
while (m--) {
int u, v;
cin >> u >> v;
--u; --v; // 转换为零索引
adjList[v].push_back(u); // 添加依赖关系
}
vector<bool> visited(n, false);
dfs(0, 0, visited, adjList, timeArray);
cout << "Minimum total cooking time is: " << minTime << endl;
return 0;
}
```
---
#### 关键点解析
1. **状态转移方程**:
在每一层递归中,考虑将尚未被加工的一道菜品加入到当前序列中,并验证其前驱节点是否均已处理完毕。
2. **剪枝优化**:
当检测到某个分支不可能优于现有结果时提前终止探索,从而减少不必要的运算开销[^2]。
3. **复杂度分析**:
时间复杂度取决于图的具体形态及其连通特性;空间消耗主要由栈帧大小决定。
---
###
阅读全文
相关推荐



