您的位置:首页 > 其它

拓扑排序+优先级队列

2015-10-26 13:33 211 查看
[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>


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: