需要安排事件顺序

Need to arrange sequence of events

我在编码面试中被问到这个问题我尝试了 hashmap、heap tree 和 queue,但没有任何效果。我想了解我错过了什么,谁能告诉我如何解决这个问题。

DESCRIPTION 现在是 2050 年。自 2045 年以来,传送已经成为可能。现在您刚刚为自己买了一台传送机器。然而。操作机器不是儿戏。在你可以传送到其他地方之前。你需要在机器上做一些安排。机器中有N个设备需要开机,各个设备之间有M种依赖关系。现在你需要弄清楚你应该打开设备的顺序以使机器启动。

输入 • 第一行将包含 2 个数字: N代表机器中的设备数量。 M代表设备依赖数量。

• 接下来的 M 行包含 2 个整数 A 和 B,表示从 A 到 B 的依赖关系(这意味着必须打开 A 才能启动 B。

输出 • 在单行中,打印机器应该打开以进行传送的顺序(由space 分隔)。 约束

• 1 <= N <= 500
• 1 <= M = N(N-1)/2 
• 1 <= A <= 500 
• 1 <  B <= 500

示例测试用例 解决方案输入:

6 6
1 2
1 3
2 5
3 4
5 6
4 6

样本输出

1 3 4 2 5 6

说明

如果你遵循这个模式。你会观察到要打开设备 6。你需要打开设备 4 和 5。要打开设备 4 和 5。我们需要分别打开设备 3 和 2。最后打开设备 3 和 2 我们需要打开设备 1。

经典的拓扑排序问题

统计每台机器需要开机的台数。

关于你的情况:

cnt[1] = 0

cnt[2] = 1 // 机器 1

cnt[3] = 1 // 机器 1

cnt[4] = 1 // 机器 3

cnt[5] = 1 // 机器 2

cnt[6] = 2 // 机器 4, 5

如果cnt等于0,表示这台机器可以开机

像这样的东西应该可以工作:

queue<int> q;
for (int i = 1; i <= n; i++)
  if (cnt[i] == 0) q.push(i);

while (!q.empty()) {
  int id = q.front(); q.pop(); // Turn on machine id
  print (id)
  for (int i = 0; i < dep[id].size(); i++) { // Dependencies for machine id
    cnt[dep[id][i]]--;
    if (cnt[dep[id][i]] == 0)
      q.push(dep[id][i]);
  }
}

问题可以改写为:

可能的算法

所需的过程称为Topological Sorting。此参考列出了一些替代算法。

一种方法是使用深度优先搜索,并在遇到节点时将其标记为已访问。不要再访问那些。从递归回溯时,将当前节点添加到输出列表中。这将确保所有依赖节点都已添加到该列表中,并且此 "ancestor" 在它们之前。