现在给出一张含有 n 个点的有向无环图,我们称这张图是“有序图”当且仅当这个图满足以下条件:
1. 存在一个 1-n 数字的全排列 p ,并令 i 号结点的权值为 p[i] 。
2. 如果图中存在 u 号结点到 v 号结点的一条边,则 u 号结点的权值要小于 v 号结点的权值。 显然可能有多个序列满足条件,请你找出字典序最小的全排列 p ,使得这个图成为有序图。
数据范围: 
第一行包含两个正整数n,m,分别表示图上结点是数量和有向边的数量。 接下来m行每行有两个正整数u,v,表示存在一条从u结点到v结点的有向边。
输出一个字典序最小的,1-n的全排列,使得这张图是有序图,元素中间使用空格隔开。
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);
}
}