输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。
给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。
其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
4 3 1 2 2 3 4 3
1 2 4 3
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.HashMap;
import java.util.PriorityQueue;
public class Main{
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;
while((line = br.readLine()) != null){
String[] params = line.split(" ");
int n = Integer.parseInt(params[0]);
int m = Integer.parseInt(params[1]);
// 图的邻接表
HashMap<Integer, LinkedList<Integer>> graph = new HashMap<>();
// 入度表
int[] inDegree = new int[n + 1];
for(int i = 0; i < m; i++){
params = br.readLine().trim().split(" ");
int p1 = Integer.parseInt(params[0]), p2 = Integer.parseInt(params[1]);
inDegree[p2]++;
if(graph.containsKey(p1)){
graph.get(p1).add(p2);
}else{
LinkedList<Integer> neighbors = new LinkedList<>();
neighbors.add(p2);
graph.put(p1, neighbors);
}
}
// 找到没有入度的队伍作为起点
PriorityQueue<Integer> queue = new PriorityQueue<>();
for(int i = 1; i <= n; i++){
if(inDegree[i] == 0){
queue.offer(i);
}
}
// 拓扑排序
String rank = topologicalSort(graph, queue, inDegree);
System.out.println(rank);
}
}
private static String topologicalSort(HashMap<Integer, LinkedList<Integer>> graph, PriorityQueue<Integer> queue, int[] inDegree) {
StringBuilder path = new StringBuilder();
// 拓扑排序
while(!queue.isEmpty()){
int cur = queue.poll();
path.append(cur).append(" ");
if(graph.containsKey(cur)){
Iterator<Integer> neighbors = graph.get(cur).iterator();
while(neighbors.hasNext()){
int next = neighbors.next();
inDegree[next]--;
if(inDegree[next] == 0){
queue.offer(next);
}
}
}
}
return path.toString().trim();
}
}