拓扑排序+优先级队列

[Description]拓扑排序,并且输出最小字典序的一个可能顺序,采用最小优先级队列可以保证按最小字典序输出。

[Input]:

输入第一行包含两个数n, m分别表示有向无环图的点数和边数。

接下来m行,每行两个数ai, bi,表示图中存在一条ai指向bi的有向边。

[Output]:输出n个数,每个数用空格隔开,表示该图的拓扑序。

拓扑排序:

1.统计每个结点的入度,将度为0的结点编号放入队列(此题放入优先队列中)中。

2.进行循环:

     ①取出队头结点,视作边的起点。

      ②删除与该点相连的边,即将这个图中的该边另一个结点(即终点)的入度减一。

      ③如果减一以后,终点的入度变为了0,那么将终点的编号入队列。

      ④判断队列是否为空,若不为空回到①。

优先级队列:

stl:priority_queue<int,vector<int>,greater<int> > q;

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=100005;
int n,m;
int a,b;
struct edge
{
	int to,next;
}e[maxn];
int in[maxn];//记录入度 
int head[maxn];
int k;
priority_queue<int,vector<int>,greater<int> > q;
void add(int u,int v)
{
	k++;
	e[k].to=v;
	e[k].next=head[u];
	head[u]=k;
}
void topp()
{
	for(int i=1;i<=n;i++)
	{
		if(in[i]==0)//入度为0
		{
			q.push(i);//入队 
			in[i]--;
		}
	}
	while(!q.empty())
	{
		int p=q.top();
		q.pop();
		printf("%d ",p);
		int p1=head[p];
		while(p1!=0)
		{
			in[e[p1].to]--;
			if(in[e[p1].to]==0) q.push(e[p1].to);
			p1=e[p1].next;
		}
	}
}
int main()
{
	freopen("topsort.in","r",stdin);
    freopen("topsort.out","w",stdout);
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d %d",&a,&b);
		add(a,b);
		in[b]++; 
	}
	topp();
	return 0;
}</span>


    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/captain_ben/article/details/49422999
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞