拓撲排序學習總結
阿新 • • 發佈:2018-11-19
原文:https://blog.csdn.net/u013480600/article/details/44809451
拓撲排序
對一個有向無環圖(Directed Acyclic Graph簡稱DAG)G進行拓撲排序,是將G中所有頂點排成一個線性序列,使得圖中任意一對頂點u和v,若邊(u,v)∈E(G),則u線上性序列中出現在v之前。
一個有向圖無法拓撲排序時只有一種情況:該有向圖中存在環。
下面給出簡單的判定有向圖是否可拓撲排序的程式碼:
題意:給你一個N點和M條有向邊的圖,問你該圖是否可拓撲排序.
分析:沒什麼可說的,直接用topo()函式判斷所給的有向圖是否可拓撲排序即可.
AC程式碼:
#include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<iomanip> #include<list> #include<map> #include<queue> #include<sstream> #include<stack> #include<string> #include<set> #include<vector> using namespace std; #define PI acos(-1.0) #define EPS 1e-8 #define MOD 1e9+7 #define LL long long #define ULL unsigned long long //1844674407370955161 #define INT_INF 0x7f7f7f7f //2139062143 #define LL_INF 0x7f7f7f7f7f7f7f7f //9187201950435737471 const int dr[]={0, 0, -1, 1, -1, -1, 1, 1}; const int dc[]={-1, 1, 0, 0, -1, 1, -1, 1}; // ios::sync_with_stdio(false); // 那麼cin, 就不能跟C的 scanf,sscanf, getchar, fgets之類的一起使用了。 const int maxn=100+10; int n,m; vector<int> G[maxn];//G[i]表示i節點所指向的所有其他點 int in[maxn];//節點入度 bool topo()//判斷該圖是否可拓撲排序 { queue<int> Q; int sum=0;//記錄可拆解的點數目 for(int i=0;i<n;i++)if(in[i]==0) Q.push(i); while(!Q.empty()) { int u=Q.front(); Q.pop(); sum++; for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(--in[v]==0) Q.push(v); } } return sum==n;//可完全拓撲 } int main() { while(scanf("%d%d",&n,&m)==2&&n) { memset(in,0,sizeof(in)); for(int i=0;i<n;i++) G[i].clear(); for(int i=0;i<m;i++) { int u,v; scanf("%d%d",&u,&v); G[u].push_back(v); in[v]++; } printf("%s\n",topo()?"YES":"NO"); } return 0; }