(QR14)带权的DAG节点排序
Posted waitti
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(QR14)带权的DAG节点排序相关的知识,希望对你有一定的参考价值。
带权的DAG节点排序
DAG即Directed Acyclic Graph,有向无环图.用DAG可以描述一些有依赖关系的任务组,而这些任务还有另外一个属性,即都有一个权重,标示这个任务的重要性.
我们需要你来实现一个算法,对DAG里面的节点进行排序,保证排序不违背DAG的依赖关系,即一个任务A如果排在任务B前面,那么在DAG中不能存在由B到A的路径.另外一个要求就是,让权重大的任务尽量优先执行.
输入:在第一行给定DAG的节点数n和边数e.后面n行,每一行是 节点的 标号和权重, seq weight.最后e行,每一行是对于边的描述, s t.
输出:排序好的节点标号,在一行内输出,空格隔开.
有依赖关系的任务很显然需要拓扑排序,即每次都选择所有依赖任务已经做完的节点,此题每个节点额外有权重,优先选择权重高的即可。由于在拓扑排序中可以使用优先队列来选择度数为0的节点,所以只需要定义一个类,重载其小于号即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int a[N], degree[N];
vector<int> forword[N];
class Node{
public:
int id;
int deg;
int weight;
bool operator < (const Node & o) const{
if(deg != o.deg)return deg < o.deg;
return weight > o.weight;
}
};
int main(){
multiset<Node> que;
int n, e, s, t, seq, w;
cin >> n >> e;
for(int i = 1;i <= n ; i++){
cin >> seq >> w;
a[seq] = w;
forword[i] = vector<int>();
}
for(int i = 1;i <= e; i++){
cin >> s >> t;
degree[t]++;
forword[s].push_back(t);
}
for(int i = 1;i <= n; i++){
// cout << degree[i] << " " << a[i] << endl;
que.insert({i, degree[i], a[i]});
}
int st = 0;
while(st < n && !que.empty()){
auto head = *que.begin();
que.erase(que.begin());
cout << head.id << " ";
for(auto i:forword[head.id]){
degree[i]--;
que.insert({i, degree[i], a[i]});
}
st++;
}
cout << endl;
}
以上是关于(QR14)带权的DAG节点排序的主要内容,如果未能解决你的问题,请参考以下文章