首页 > 试题广场 >

有序图

[编程题]有序图
  • 热度指数:1158 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
现在给出一张含有 个点的有向无环图,我们称这张图是有序图当且仅当这个图满足以下条件:
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
逆向拓扑排序+优先队列,满足拓扑关系的前提下,将节点值大的往后放
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue;

/**
 * @Author: coderjjp
 * @Date: 2020-05-11 22:27
 * @Description:
 * @version: 1.0
 */
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] line1 = br.readLine().split(" ");
        int n = Integer.parseInt(line1[0]);
        int m = Integer.parseInt(line1[1]);
        int hash[] = new int[n+1];//记录1-n的出度
        ArrayList<Integer> from[] = new ArrayList[n+1];//记录每个点被谁指向
        for (int i = 0; i < m; i++){
            String line[] = br.readLine().split(" ");
            int f = Integer.parseInt(line[0]);
            int t = Integer.parseInt(line[1]);
            if (from[t] == null)
                from[t] = new ArrayList<>();
            from[t].add(f);
            hash[f]++;
        }
        //维护一个最大优先队列
        PriorityQueue<Integer> queue = new PriorityQueue<>((o1, o2) -> o2 - o1);//将出度为0的进队
        for (int i = 1; i <= n; i++)
            if (hash[i] == 0)
                queue.offer(i);
        int ans[] = new int[n+1];//记录1-n个节点的权重
        int w = n;
        while (!queue.isEmpty()){
            int cur = queue.poll();
            ans[cur] = w;
            w--;
            if (from[cur] != null)
                for (int i: from[cur]){
                    hash[i]--;
                    if (hash[i] == 0)
                        queue.offer(i);
                }
        }
        StringBuilder res = new StringBuilder().append(ans[1]);
        for (int i = 2; i <= n; i++)
            res.append(" ").append(ans[i]);
        System.out.println(res);
    }
}


发表于 2020-05-11 22:43:30 回复(1)