解题思路
这是一道拓扑排序问题:
- 每道菜品的品尝顺序可以看作有向图中的节点
- "前置菜肴"的要求可以看作有向边
- 如果存在合法的品尝顺序,则图中不存在环
- 使用拓扑排序算法可以得到一个合法的品尝顺序
解题步骤:
- 构建邻接表表示图结构
- 计算每个节点的入度
- 将入度为0的节点加入队列
- 不断取出队首节点,减少其相邻节点的入度
- 如果最终访问的节点数小于总节点数,说明存在环,返回None
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m;
scanf("%d%d", &n, &m);
// 构建图和入度数组
vector<vector<int>> graph(n);
vector<int> indegree(n, 0);
for(int i = 0; i < m; i++) {
int u, v;
scanf("%d%d", &u, &v);
graph[v].push_back(u); // v必须在u之前吃
indegree[u]++;
}
// 拓扑排序
queue<int> q;
for(int i = 0; i < n; i++) {
if(indegree[i] == 0) q.push(i);
}
vector<int> ans;
while(!q.empty()) {
int curr = q.front();
q.pop();
ans.push_back(curr);
for(int next : graph[curr]) {
if(--indegree[next] == 0) {
q.push(next);
}
}
}
// 输出结果
if(ans.size() < n) {
printf("None\n");
} else {
for(int i = 0; i < n - 1; i++) {
printf("%d,", ans[i]);
}
printf("%d\n", ans.back());
}
return 0;
}
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
// 构建图和入度数组
List<List<Integer>> graph = new ArrayList<>();
for(int i = 0; i < n; i++) {
graph.add(new ArrayList<>());
}
int[] indegree = new int[n];
for(int i = 0; i < m; i++) {
int u = sc.nextInt();
int v = sc.nextInt();
graph.get(v).add(u);
indegree[u]++;
}
// 拓扑排序
Queue<Integer> q = new LinkedList<>();
for(int i = 0; i < n; i++) {
if(indegree[i] == 0) q.offer(i);
}
List<Integer> ans = new ArrayList<>();
while(!q.isEmpty()) {
int curr = q.poll();
ans.add(curr);
for(int next : graph.get(curr)) {
if(--indegree[next] == 0) {
q.offer(next);
}
}
}
// 输出结果
if(ans.size() < n) {
System.out.println("None");
} else {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < ans.size() - 1; i++) {
sb.append(ans.get(i)).append(",");
}
sb.append(ans.get(ans.size() - 1));
System.out.println(sb.toString());
}
}
}
from collections import defaultdict, deque
def solve(n, m, prerequisites):
# 构建图和入度数组
graph = defaultdict(list)
indegree = [0] * n
for u, v in prerequisites:
graph[v].append(u)
indegree[u] += 1
# 拓扑排序
q = deque([i for i in range(n) if indegree[i] == 0])
ans = []
while q:
curr = q.popleft()
ans.append(curr)
for next_node in graph[curr]:
indegree[next_node] -= 1
if indegree[next_node] == 0:
q.append(next_node)
# 返回结果
return None if len(ans) < n else ','.join(map(str, ans))
n, m = map(int, input().split())
prerequisites = []
for _ in range(m):
u, v = map(int, input().split())
prerequisites.append((u, v))
result = solve(n, m, prerequisites)
print(result if result is not None else "None")
算法及复杂度
- 算法:拓扑排序(BFS实现)
- 时间复杂度:
- 其中
是节点数,
是边数
- 空间复杂度:
- 需要存储图结构和队列