[hdu 1285] (http://acm.hdu.edu.cn/showproblem.php?pid=1285)
题目描述:
确定比赛名次
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 17588 Accepted Submission(s): 7026
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
题目分析:
1. 此题建图运用链式前向星的方法;
2. 利用拓扑排序时,加入优先队列,可以实现自动从小到大的排序,即可以实现题目中所要求的序号小的排在前面,具体代码实现如下:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
#include <vector>
#include <functional>
using namespace std;
const int N=505;
int head[N*N];
int ip;
int n,m,p1,p2,seq[N*N];
int indegree[N];//用于存储点的入度
struct edgenode
{
int to;
int next;
} edge[N*N];
void add(int u,int v)
{
edge[ip].to=v;
edge[ip].next=head[u];
head[u]=ip++;
}
int tope()
{
priority_queue<int,vector<int>,greater<int> >q;//利用优先队列从小到大进行排序
int indeg[N];
for(int i=1; i<=n; i++)
{
indeg[i]=indegree[i];
if(indeg[i]==0)//将入度为0的下标插入队列队尾
q.push(i);
}
int k=0;
bool res=false;
while(!q.empty())//当队列不为空时
{
if(q.size()!=1) res=true;
int u=q.top();//把队首元素赋给u //1. int u=q.top();在优先队列中使用 //2. int u=q.front();在普通队列中使用
q.pop();//删除队首元素
seq[k++]=u;
for(int i=head[u]; i!=-1; i=edge[i].next)
{
int v=edge[i].to;
indeg[v]--;
if(indeg[v]==0)//将入度为0的下标插入队列队尾
q.push(v);
}
}
//if(k<n) return -1;//存在有向环,不能进行拓扑排序
if(res) return 0;//排序有唯一种解,seq数组即为排好的
return 1;//排序有多种解,由于经过STL队列处理,seq为序号最小的一种
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(head,-1,sizeof(head));
ip=0;
memset(indegree,0,sizeof(indegree));
memset(seq,0,sizeof(seq));
for(int i=0; i<m; i++)
{
scanf("%d%d",&p1,&p2);
add(p1,p2);
indegree[p2]++;//记录入度
}
int t=tope();
if(t==0||t==1)
for(int i=0; i<n; i++)
{
printf(i==n-1?"%d\n":"%d ",seq[i]);
}
}
return 0;
}