【拓扑排序】有向无环图拓扑排序 - 最小平均响应时间安排

常见算法 同时被 2 个专栏收录
13 篇文章 0 订阅
58 篇文章 0 订阅

  有向无环图的拓扑排序在 https://blog.csdn.net/Bob__yuan/article/details/95613891 也有记录,是通过拓扑排序查看一个图是不是无环的。
  这篇文章记录的是另一种用法,就是用有向图来表示任务的依赖关系,然后通过拓扑排序找出按照依赖关系前后顺序完成所有任务的方法。百度里介绍拓扑排序也是说拓扑排序就是这个目的。
  就比如说,有 n 个任务需要执行,但是有的任务和任务之间是有依赖关系的,比如穿毛裤之前肯定要先穿秋裤这种感觉。题目是:第一行给出两个正整数 nmn 表示任务总数,m 表示有 m 个依赖关系,下边一行是 n 个正整数,表示每个任务需要花费的时间(任务从 1 开始计数),接下来 m 行每行两个正整数 xi 、yi 表示 yi 依赖 xi,也就是 xi 必须在 yi 之前完成。如果一个任务必须完成了才能开始新的任务,怎么能让所有任务平均等待时间最短。
  肯定要让完成所需时间短的任务先完成,所以需要一个优先队列,还需要考虑的是,先让所有入度 为0(也就是不依赖别的任务)的任务进队列,然后每次有任务完成,如果有任务依赖它,那这个任务的入度就减少1,如果入度减少为 0,说明这个任务前边的依赖任务已经都完成了,就让它入队,代码如下:

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

vector<int> need_time;

struct cmp {
	bool operator()(int i, int j) {
		if (need_time[i] != need_time[j])
			return need_time[i] > need_time[j];
		else
			return i > j;
	}
};

int main() {
	int n, m;		// n 个任务,m 个依赖关系
	cin >> n >> m;
	need_time = vector<int>(n + 1);
	vector<int> ins(n + 1, 0);			// 每个节点的入度
	vector<pair<int, int>> req(m + 1);	// require
	for (int i = 1; i <= n; ++i)
		cin >> need_time[i];
	for (int i = 1; i <= m; ++i){
		cin >> req[i].first >> req[i].second;
		++ins[req[i].second];
	}

	priority_queue<int, vector<int>, cmp> q;

	// 入度为0(不依赖别的任务)的任务入队
	for (int i = 1; i <= n; ++i)
		if(ins[i] == 0)
			q.push(i);
	while (!q.empty())
	{
		auto tmp = q.top();
		cout << tmp << " ";
		q.pop();
		for (auto ite = req.begin(); ite != req.end();)	{
			if (ite->first == tmp) {
				if (--ins[ite->second] == 0)
					q.push(ite->second);
				ite = req.erase(ite);
			}
			else
				++ite;
		}
	}
}

  也可以把任务依赖关系用一个 unordered_map<int, unordered_set< int >> 来存储,这样每次就不需要遍历了。

  • 0
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值