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]++;
			}
		}
	}

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章