拓扑排序
题目链接:点击打开链接
确定比赛名次
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 26752 Accepted Submission(s): 10732
Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。
Input 输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。
Output 给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。
其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
Sample Input
4 3 1 2 2 3 4 3
Sample Output
1 2 4 3
题目大意:
给出n个队伍,已经m条比赛记录,最后输出排名。当符合条件的排名不是唯一的时,编号小的队伍在前
解题思路:
把n个队伍,看成n个结点。m条比赛记录,看成m条有向边。使用图的邻接矩阵来存储图。
对这个图进行拓扑排序。
代码实现:
package cn.hncu.serch.topSort;
import java.util.Scanner;
public class P1285_2 {
static Scanner sc=new Scanner(System.in);
static int n; //n个顶点
static int m; //m条边
static int sorted[]; //每个顶点是否处于排序的状态
static int drgee[]; //每个顶点的入度数
static int arc[][]; //有向边的集合
/**
* 进行拓扑排序
*/
private static void topSort() {
//因为这个题目是有解的,所以拓扑排序一定能够进行到最后
//也就是说最后进行拓扑排序的点为n个
int count=0; //记录已经排序了的点
while(count<n){
int i=0;
for(;i<n;i++){
//遍历所有的点,找到入度为0 并且为排序的结点。该顺序是从小到大,符合题目要求当有多组解时编号小的队伍在前面
if(drgee[i]==0 && sorted[i]==0){
break; //这里找到一个结点就要break;为了下一次再次从0开始查找
// for(int j=0;j<n;j++){
// //遍历n个结点,找到正在进行排序的这个点的子节点(也就是该结点是否有边相连)
// if(arc[i][j]==1){
// drgee[j]--; //结点j的入度减一.
// }
// }
}
}
//找到一个结点后,设置该结点排序状态
sorted[i]=1; //表示已经排出该结点
count++; //记录结点数++;
//输出该结点
if(count<n){
System.out.print((i+1)+" ");
}else{
System.out.println(i+1);
}
for(int j=0;j<n;j++){
//遍历n个结点,找到正在进行排序的这个点的子节点(也就是该结点是否有边相连);消边。
if(arc[i][j]==1){
drgee[j]--; //结点j的入度减一.
}
}
}
}
/**
* 图的输入以及初始化
*/
private static void init() {
sorted =new int[n]; //sorted[]=0表示未排序
drgee=new int[n];
arc=new int[n][n]; //图的邻接矩阵
for(int i=0;i<m;i++){
int a=sc.nextInt()-1; //a,b表示数组下标,所以减一
int b=sc.nextInt()-1; //a==>b的边
if(arc[a][b]==0){ //防止出现重复边
arc[a][b]=1;
drgee[b]++; //b的入度增加1
}
}
}
public static void main(String[] args) {
while(sc.hasNext()){
n=sc.nextInt(); //n个顶点,
m=sc.nextInt(); //m条边,
init(); //图的初始化
topSort(); //拓扑排序
}
}
}