1. 程式人生 > >Ordering Tasks UVA - 10305(拓撲排序)

Ordering Tasks UVA - 10305(拓撲排序)

size main std 有環 eof color 完全 一個 技術

在一個有向圖中,對所有的節點進行排序,要求沒有一個節點指向它前面的節點。

先統計所有節點的入度,對於入度為0的節點就可以分離出來,然後把這個節點指向的節點的入度減一。

一直做改操作,直到所有的節點都被分離出來。

如果最後不存在入度為0的節點,那就說明有環,不存在拓撲排序,也就是很多題目的無解的情況。

下面是算法的演示過程。

技術分享圖片

下面看一道例題

題目鏈接:https://vjudge.net/problem/UVA-10305

技術分享圖片

代碼真的很簡單 ,完全是水題。

看代碼:

#include<iostream>
#include<queue>
#include<vector>
#include
<string.h> using namespace std; const int maxn=100+5; int N,M; int in[maxn];//表示該節點的入度 int edge[maxn][maxn];//edge[i][j]不為0表示i到j有路 void solve() { queue<int> q; vector<int>ans; for(int i=1;i<=N;i++) { if(in[i]==0) q.push(i);//入度為0的結點入隊列 } while(!q.empty()) {
int p=q.front(); q.pop(); ans.push_back(p);//拿出入度為0的結點 for(int i=1;i<=N;i++)//與該結點之間有邊的入度減1 { if(edge[p][i]) { edge[p][i]--; in[i]--; if(in[i]==0) q.push(i);//入度減為0 入隊列 } } } cout
<<ans[0]; for(int i=1;i<ans.size();i++) cout<<" "<<ans[i]; cout<<endl; return ; } int main() { int a,b; while(cin>>N>>M) { if(N==0&&M==0) break; memset(edge,0,sizeof(edge)); memset(in,0,sizeof(in)); for(int i=0;i<M;i++) { cin>>a>>b; in[b]++; edge[a][b]++; } solve(); } return 0; }



Ordering Tasks UVA - 10305(拓撲排序)