有向图的拓扑序列

时间:2022-05-27 22:54:47   收藏:0   阅读:7

 

步骤:

1.输入边时将入度加1;

2.在bfs函数中将所有入度为0的点入队;

3.如果下个点可达,则的入度--,如果入度为0, 将其入度。

/*题目要求:本题要求是求出有向图中的任意一个拓扑序列,有则输出这个序列,没有则输出-1;
*思路:一个点的入度为0,代表没有点指向它,所以它可以入队,接着搜索下一个可以到达点,
*并删除它与下一个点之间的边,若下一个点入度也为0,则也入队...
*/
#include<iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 1e5+10;
int n, m;
int h[N], e[N], ne[N], idx;
// q[N]存放是队列,d[N]存放的是每个点的入度
int q[N], d[N];

void add(int a, int b)  // 添加一条边a->b
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}

bool bfs()
{
    int hh = 0, tt = -1;
    //将入度为零的点入队
    for(int i=1;i<=n;i++)
        if(!d[i]) q[++tt]=i;
    while(hh <= tt)
    {
        //取出队头
        int t = q[hh++];
        for(int i = h[t]; i != -1; i = ne[i])
        {
            //下一个可以走的结点
            int j = e[i];
            //删除掉这条边
            d[j] -- ;
            if(d[j] == 0) q[++tt] = j;
        }
    }
    //当这个图为拓扑图的时候,则所有结点都会入队;
    return tt == n - 1?true:false;
}

int main()
{
    cin>>n>>m;
    memset(h,-1,sizeof h);
    for(int i = 0; i < m; i++)
    {
        int a, b;
        cin>>a>>b;
        add(a, b);
        d[b]++;
    }
    
    if(bfs())
    {
        for(int i=0;i<n;i++)
            cout<<q[i]<<" ";
            cout<<endl;
    }
    else
    {
        cout<<"-1"<<endl;
    }
    
    return 0;
}
 

 

原文:https://www.cnblogs.com/wangchuang-blog/p/15358808.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!