现在的位置: 首页 > 综合 > 正文

【HDU】1285 确定比赛名次 拓扑排序

2017年10月15日 ⁄ 综合 ⁄ 共 1874字 ⁄ 字号 评论关闭

确定比赛名次

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10963    Accepted Submission(s): 4374

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
 


Author

SmallBeer(CML)
 


Source

杭电ACM集训队训练赛(VII)

传送门:【HDU】1285 确定比赛名次

题目分析:拓扑排序,用到优先队列。

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;

#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REPV( i , a , b ) for ( int i = a ; i >= b ; -- i )
#define clear( a , x ) memset ( a , x , sizeof a )

typedef long long Int ; 

const int MAXN = 505 ;
const int MAXE = 1000000 ;

struct Edge {
	int v , n ;
} ;

struct priority_queue {
	int heap[MAXN] ;
	int top ;
	
	void init () {
		top = 1 ;
	}
	
	void push ( int x ) {
		heap[top] = x ;
		int o = top ++ ;
		while ( o > 1 && heap[o] < heap[o >> 1] )
			swap ( heap[o] , heap[o >> 1] ) , o >>= 1 ;
	}
	
	int empty () {
		return top == 1 ;
	}
	
	int front () {
		return heap[1] ;
	}
	
	void pop () {
		heap[1] = heap[-- top] ;
		int o = 1 , p = o , l = o << 1 , r = o << 1 | 1 ;
		while ( o < top ) {
			if ( l < top && heap[l] < heap[p] )
				p = l ;
			if ( r < top && heap[r] < heap[p] )
				p = r ;
			if ( p == o )
				break ;
			swap ( heap[o] , heap[p] ) ;
			o = p , l = o << 1 , r = o << 1 | 1 ;
		}
	}
} ;

priority_queue q ;
Edge edge[MAXE] ;
int adj[MAXN] , cntE ;
int in[MAXN] ;
int ans[MAXN] , cnt ;
int n , m ;

void addedge ( int u , int v ) {
	edge[cntE].v = v ; edge[cntE].n = adj[u] ; adj[u] = cntE ++ ;
}

void DAG () {
	q.init () ;
	cnt = 0 ;
	REPF ( i , 1 , n )
		if ( !in[i] )
			q.push ( i ) ;
	while ( !q.empty () ) {
		int u = q.front () ;
		q.pop () ;
		ans[++ cnt] = u ;
		for ( int i = adj[u] ; ~i ; i = edge[i].n ) {
			int v = edge[i].v ;
			if ( 0 == ( -- in[v] ) )
				q.push ( v ) ;
		}
	}
}

void work () {
	int u , v ;
	while ( ~scanf ( "%d%d" , &n , &m ) ) {
		clear ( adj , -1 ) ;
		clear ( in , 0 ) ;
		cntE = 0 ;
		while ( m -- ) {
			scanf ( "%d%d" , &u , &v ) ;
			++ in[v] ;
			addedge ( u , v ) ;
		}
		DAG () ;
		REPF ( i , 1 , n )
			printf ( "%d%c" , ans[i] , i < n ? ' ' : '\n' ) ;
	}
}

int main () {
	work () ;
	return 0 ;
}

抱歉!评论已关闭.