拓撲排序是對有向無環圖(dag)進行排序,從而找到乙個序列。該序列滿足對於任意一對不同的頂點u,v∈v,若g中存在一條從u->v的邊,則在此序列中u在v前面。
拓撲排序也可以用來判斷乙個有向圖是否存在環。
有兩種演算法可以求得該序列:
1.kahn演算法。
其實就是不斷的尋找有向圖中沒有前驅(入度為0)的頂點,將之輸出。然後從有向圖中刪除所有以此頂點為尾的弧。重複操作,直至圖空,或者找不到沒有前驅的頂點為止。
該演算法還可以判斷有向圖是否存在環(存在環的有向圖肯定沒有拓撲序列),通過乙個count記錄找出的頂點個數,如果少於n則說明存在環使剩餘的頂點的入度不為0。(degree陣列記錄每個點的入度數)
#include#define n 100010
using namespace std;
namespace program
inline void add(int u,int v)
inline bool kahn()
} if(cnt^n)
return 0;
return 1;
} inline void work()
for(int i=1;i<=n;i++)
if(kahn())else }}
int main()
2.基於dfs的求解方法。
演算法導論對於該種方法講述的比較詳細,由於它用的單鏈表存邊,下面我只貼乙份自己的模板**。
思想基於:dfs時候,遇到u->v邊,通過在dfs函式快退出時將結點加入到list中實現v在序列的位置始終在u的前面。反向序列即為所求的拓撲序列。
#include#define n 100010
using namespace std;
namespace program
inline void add(int u,int v)
inline void dfs(int k)
ans.push_back(k);
} inline void work()
for(int i=1;i<=n;i++)
if(!limit[i])
dfs(i);
list::reverse_iterator it;
for(it=ans.rbegin();it!=ans.rend();it++)
cout<<*it<<" ";
puts("");
return; }}
int main()
拓撲排序 專題)
解題報告 拓撲排序的板子題,不想說了。解題報告 這道題看到第一反應是差分約束,然後拓撲排序也可以做,由於所有的邊都是大於0的,如果存在環一定無解 就是拓撲排序佇列長度不是n就說明存在環 在建邊上,因為是最長路所以採用a b w,b向a連一條w的邊,然後從後往前找最長路,由於每個人獎金初始值都是100...
拓撲排序模板
include include include include include using namespace std const int maxn 30 int head maxn ip,indegree maxn int n,m,seq maxn struct note edge maxn ma...
模板 拓撲排序
拓撲排序 將 小於 關係看做有向圖,形成一條排好序的關係,可能不唯一。queue實現,vector儲存 const int maxn 10005 int in maxn sum,n,m,fa maxn vectorg maxn void init void toposort 按字典序輸出 改為pri...