Hdu1285 拓扑排序-确定比赛名次

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

import java.util.Scanner;

/**
 * @author YouYuan
 * @eMail E-mail:[email protected]
 * @Time 创建时间:2015年8月11日 上午11:39:48
 * @Explain 说明:本程序默认从编号小的开始排序,所以得出的解便是最小的在前面
 */
public class 拓扑排序_确定比赛名次 {

	static Scanner in = new Scanner(System.in);
	static int MAXN = 501;
	static int n, m;
	static int[][] arc = new int[MAXN][MAXN];// 邻接矩阵,用于储存两个队伍之间的关系
	static boolean[] visited = new boolean[MAXN];// 用于存储当前顶点(队伍)是否已经访问过了
	static int[] degree = new int[MAXN];// 存储每个顶点的入度数(队伍的前驱数)

	public static void main(String[] args) {
		while (in.hasNext()) {
			n = in.nextInt();
			m = in.nextInt();
			initialise();
			structure();
			topologySort();
		}
	}

	/**
	 * 初始化
	 */
	private static void initialise() {
		for (int i = 0; i < n; i++) {
			visited[i] = false;
			degree[i] = 0;
			for (int j = 0; j < n; j++) {
				arc[i][j] = 0;
			}
		}
	}

	/**
	 * 拓扑排序并输出结果
	 */
	private static void topologySort() {
		int sum = 0;//已经排序的顶点数
		while(sum < n) {
			int i;//存储入度为0的顶点的下标
			for (i = 0; i < n; i++) {//查找入度为0并且没有访问过的顶点,即图的起点(排名最靠前的)
				if (degree[i]==0 && !visited[i]) {
					break;
				}
			}
			if (i == n) {//若i==n,说明当前图中无入度为0的顶点,是一个回路
				System.out.println("图中有回路,无解");
				return;
			}
			visited[i] = true;//标记当前顶点已访问
			System.out.print(i+1);//输出编号
			sum++;
			System.out.print(sum < n ? " " : "");
			for (int j = 0; j < n; j++) {
				if (arc[i][j] == 1) {
					degree[j]--;//以当前排序了的顶点为前驱的顶点的入度-1
				}
			}
		}
		System.out.println();
	}

	/**
	 * 构造图
	 */
	private static void structure() {
		
		while (--m >= 0) {
			int a = in.nextInt() - 1;
			int b = in.nextInt() - 1;
			if (arc[a][b] == 0) {//去除重复数据
				arc[a][b] = 1;
				degree[b]++;
			}
		}
	}

}


你可能感兴趣的:(Acm-图论)