Ordering Tasks UVA - 10305(拓撲排序)
阿新 • • 發佈:2019-02-16
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(拓撲排序)