列表

详情


QR14. 带权的DAG节点排序

描述

DAG即Directed Acyclic Graph,有向无环图.用DAG可以描述一些有依赖关系的任务组,而这些任务还有另外一个属性,即都有一个权重,标示这个任务的重要性.

我们需要你来实现一个算法,对DAG里面的节点进行排序,保证排序不违背DAG的依赖关系,即一个任务A如果排在任务B前面,那么在DAG中不能存在由B到A的路径.另外一个要求就是,让权重大的任务尽量优先执行.

输入描述

在第一行给定DAG的节点数n和边数e.

后面n行,每一行是 节点的 标号和权重, seq weight.

最后e行,每一行是对于边的描述, s t.

输出描述

排序好的节点标号,在一行内输出,空格隔开.

示例1

输入:

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

输出:

1 3 2 4

原站题解

C++ 解法, 执行用时: 2ms, 内存消耗: 288KB, 提交时间: 2021-07-26

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

int main(void) {
  int n, e;
  cin >> n >> e;
  vector<int> weights(n + 1);
  
  int seq, w;
  for (int i = 0; i < n; ++i) {
    cin >> seq >> w;
    weights[seq] = w;
  }
  
  int u, v;
  vector<vector<int>> g(n + 1);
  vector<int> indegrees(n + 1, 0);
  for (int i = 0; i < e; ++i) {
    cin >> u >> v;
    g[u].emplace_back(v);
    ++indegrees[v];
  }
  
  priority_queue<pair<int, int>> q; // maximum heap
  for (int u = 1; u <= n; ++u) 
    if (!indegrees[u]) q.emplace(weights[u], u);
  
  while (not q.empty()) {
    const auto [weight, curr] = q.top(); q.pop();
    cout << curr << ' ';
    for (const int nxt : g[curr])
      if (!--indegrees[nxt]) q.emplace(weights[nxt], nxt);
  }
  
  return 0;
}

C++ 解法, 执行用时: 2ms, 内存消耗: 300KB, 提交时间: 2022-01-23

#include <bits/stdc++.h>
using namespace std;

unordered_map<int, vector<int>> adj;

vector<int> w;

bool cmp(int o1, int o2)
{
    return w[o1] > w[o2];
}

int main()
{
    int n, e; //节点数 和 边数
    scanf("%d %d", &n, &e);
    vector<int> indegree(n + 1, 0); //每个节点的入度
    w = vector<int>(n + 1, 0);      //每个节点的权重
    for (int i = 1; i <= n; i++)
    {
        int vex, weight;
        scanf("%d %d", &vex, &weight);
        w[vex] = weight;
    }
    for (int i = 1; i <= e; i++)
    {
        int vex1, vex2;
        scanf("%d %d", &vex1, &vex2);
        indegree[vex2]++; //入度
        adj[vex1].push_back(vex2);
    }
    for (auto it = adj.begin(); it != adj.end(); it++)
    {
        sort(it->second.begin(), it->second.end(), cmp);
    }
    vector<int> a;
    queue<int> queue;
    for (int i = 1; i <= n; i++)
    {
        if (indegree[i] == 0)
        {
            a.push_back(i);
        }
    }
    sort(a.begin(), a.end(), cmp);
    for (int i = 0; i < a.size(); i++)
        queue.push(a[i]);
    while (queue.empty() == false)
    {
        int t = queue.front();
        queue.pop();
        printf("%d ", t);
        a.clear();
        for (int i = 0; i < adj[t].size(); i++)
        {
            if (--indegree[adj[t][i]] == 0)
            {
                a.push_back(adj[t][i]);
            }
        }
        sort(a.begin(), a.end(), cmp);
        for (int i = 0; i < a.size(); i++)
            queue.push(a[i]);
    }
    //system("pause");
    return 0;
}

上一题