列表

详情


JD18. 有序图

描述

现在给出一张含有 个点的有向无环图,我们称这张图是有序图当且仅当这个图满足以下条件:
1. 存在一个 1-n 数字的全排列 ,并令 号结点的权值为 p[i] 
2. 如果图中存在 号结点到 号结点的一条边,则 号结点的权值要小于 号结点的权值。 显然可能有多个序列满足条件,请你找出字典序最小的全排列 ,使得这个图成为有序图。
数据范围:

输入描述

第一行包含两个正整数n,m,分别表示图上结点是数量和有向边的数量。 接下来m行每行有两个正整数u,v,表示存在一条从u结点到v结点的有向边。

输出描述

输出一个字典序最小的,1-n的全排列,使得这张图是有序图,元素中间使用空格隔开。

示例1

输入:

3 3
1 2
1 3
3 2

输出:

1 3 2

原站题解

C++14 解法, 执行用时: 47ms, 内存消耗: 8420KB, 提交时间: 2020-07-28

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
   
vector<int> solve(vector<vector<int>> &adj, vector<int> &in, int n)
{
    priority_queue<int> q;
    vector<int> ret(n+1);
    int cnt = n;
       
    for (int i=1; i<=n; i++)
        if (in[i]==0)
            q.push(i);
       
    while (!q.empty())
    {
        int t = q.top();
        q.pop();
        ret[t] = cnt--;
        for (int i=0; i<adj[t].size(); i++)
            if (--in[adj[t][i]]==0)
                q.push(adj[t][i]);
    }
       
    return ret;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n, k;
    cin >> n >> k;
    vector<vector<int>> adj(n+1);
    vector<int> in(n+1, 0);
       
    for (int i=0; i<k; i++)
    {
        int u, v;
        cin >> u >> v;
        adj[v].push_back(u);
        in[u]++;
    }
       
    vector<int> ret = solve(adj, in, n);
    for (int i=1; i<=n; i++)
        cout << ret[i] << " ";
    return 0;
}

C++ 解法, 执行用时: 49ms, 内存消耗: 7196KB, 提交时间: 2020-10-29

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
  
vector<int> solve(vector<vector<int>> &adj, vector<int> &in, int n)
{
    priority_queue<int> q;
    vector<int> ret(n+1);
    int cnt = n;
      
    for (int i=1; i<=n; i++)
        if (in[i]==0)
            q.push(i);
      
    while (!q.empty())
    {
        int t = q.top();
        q.pop();
        ret[t] = cnt--;
        for (int i=0; i<adj[t].size(); i++)
            if (--in[adj[t][i]]==0)
                q.push(adj[t][i]);
    }
      
    return ret;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n, k;
    cin >> n >> k;
    vector<vector<int>> adj(n+1);
    vector<int> in(n+1, 0);
      
    for (int i=0; i<k; i++)
    {
        int u, v;
        cin >> u >> v;
        adj[v].push_back(u);
        in[u]++;
    }
      
    vector<int> ret = solve(adj, in, n);
    for (int i=1; i<=n; i++)
        cout << ret[i] << " ";
    return 0;
}

上一题