HDU - 1285 (拓扑排序)

HDU - 1285 (拓扑排序)

有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

  • 拓扑排序
    对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。这是百度百科上的解释,我理解的就是在某些情况下只有前面的事做完了才能做后面的事 然后让你找一个完整的步骤。
  • 解题步骤:
    a.先把图用邻接表的形式存下来
    b.然后找入度为0 的点入队,小细节的地方就是这个题要用优先队列,因为答案可能有很多种,题目要求小的数在前面,所以每次取的队首元素都是队列里面最小的。
    c.取出队首这个点后,把这个点连接的点的入度都减一,每次判断一下入度为0吗,为0就入队。用一个ans数记录一下答案(这个ans数组还能判断有没有正确答案,最后如果数组里的元素少于n说明无解)
    d.一直到队列为空为止,输出ans数组。
    代码如下:

#include <bits/stdc++.h> 
using namespace std;
const int maxn = 1e5+7;
struct node{
	int id;
	int d;
	int next;
}side[maxn];///记录一条边 id-next权值为d 
int head[maxn];
int cnt=0;
void init(int n)
{
	memset(head,-1,sizeof(head));
	cnt=0;
}
void add(int x,int y)
{
	side[cnt].id=y;
	side[cnt].d=0;
	side[cnt].next=head[x];///头部插入 
	head[x]=cnt++; 
}
int in[maxn];///用来记录入度 
int ans[maxn];///用来记录答案 防止没有正确排序的情况,但是这个题保证一定有 所以可以不用这个
int main()
{
	int n,m;

	while(cin>>n>>m)
	{
		init(n);
		memset(in,0,sizeof(in));
		for(int i=0;i<m;i++)
		{
			int x,y;
			scanf("%d%d",&x,&y);
			add(x,y);//连接x和y构成一条边 因为没有权值 权值可以随意赋值 
			in[y]++;//y的入度+1;			
		}
	
		priority_queue <int, vector<int>,greater<int> > qq;////建一个优先队列
		for(int i=1;i<=n;i++)
		{
			if(in[i]==0)///把起初入度为0的点入队 
				qq.push(i);
		} 
		int k=0;
		while(qq.size())
		{
			int x0=qq.top();///入度为0的最小的点
			ans[k++]=x0;///记录下答案
			qq.pop();///记录完了就吧这个出队
			for(int i=head[x0];i!=-1;i=side[i].next)
			{
				int y0=side[i].id;
				in[y0]--;
				if(in[y0]<=0)
					qq.push(y0);
			} 
		}
		for(int i=0;i<k;i++)
		{
			printf(i == k-1 ?"%d\n":"%d ",ans[i]);
		} 
	} 
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/weixin_43179892/article/details/83477307
今日推荐