有向圖的拓撲序列


 

步驟:

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;
}
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM