基本思想:
拓撲序列滿足,入度為0的點進入序列,且該點的出邊點的入度-1
,
如果該點出邊的入度為0
,則重複第1步
鄰接表+bfs
開乙個陣列記錄所有點的入度,將入度為0
的點加入到佇列
取出隊頭,加入到拓撲序.
更新出邊的點的入度,判斷是否為0
,為0
加入佇列
重複2 3
知道隊列為空
判斷是否存在拓撲序列(既不存在入度為0的點)#include using namespace std;
,且入度不為const int maxn = 1e6;
int head[maxn];
int next1[maxn];
int ver[maxn];
int tot = 0;
int deg[maxn];
void add(int u,int v)
vectorans;
void topsort() }}
int main()
topsort();
for (int i=0; i鄰接表+dfs
dfs回溯時肯定下面的點都走過或者該點為葉子節點(出度一定為0
0
),出邊的終點沒有走過,往下面走,能想象到每次入棧的一定是從下到上的點,
正好符合前驅後繼的關係
每個點都dfs一次,標記的點不dfs,
那麼把所有點分成兩個集合,乙個是待處理的點集d,乙個是已拓撲排序後的點集a,當且僅當d中某個點沒有後繼結點(或該後繼結點已經加入了點集a中)時,此時將點從d轉移到a,回溯恰好滿足這個操作
#include using namespace std;
const int maxn = 1e5;
int head[maxn];
//int val[maxn];
int next1[maxn];
int ver[maxn];
int tot = 0;
stackans;
void add(int u,int v)
bool vis[maxn];
int dfs(int x)
ans.push(x);
}int main()
for (int i=1; i<=n; i++)
// stack最後push進去的一定是沒有出度的點,或者後續節點已經入棧,間接的想到最後push進去的點一定是 入度等於0的點
while (!ans.empty())
return 0;
}
#include using namespace std;
const int maxn = 1e5;
int tot = 0;
int head[maxn];
int next1[maxn];
int ver[maxn];
int vis[maxn];
int n,m;
stackans;
void add(int u,int v)
bool dfs(int x)
vis[x] = -1;
ans.push(x);
return true;
}int main()
bool flag = true;
for (int i=1; i<=n; i++)
} while ( flag && !ans.empty() )
return 0;
}
模板 拓撲序列
拓撲序列有很多用途,比如判環,將樹上 圖上的問題轉化為序列上的問題再處理等等 尋找過程就是不斷找入度為0的點新增到q尾部 如果得到的拓撲序列長度不等於n 則說明有環 void toposort int n while q.empty 例題 可達性統計 此題可以用拓撲序 暴力合併解決 原因 題目給出了...
AOV網路 拓撲排序 拓撲序列
aov網是有向圖的一類應用,在aov網中,用頂點表示某個有一定規模的 工程 裡的不同活動,用圖中的邊表示各項活動之間的先後順序關係。一種常見的aov網例項是大學課程的先修關係,以下 列出了計算機專業若干課程及其先修課程 課程編號 課程名稱 先修課程 c1高等數學 c2程式設計基礎 c3資料結構 c1...
拓撲序列以及排序
一句話題意 求aov網的拓撲序列,輸出按字典序最小的乙個。拓撲排序 由aov網構造拓撲序列的拓撲排序演算法主要是迴圈執行以下兩步,直到不存在入度為0的頂點為止。1 選擇乙個入度為0的頂點並輸出之 2 從網中刪除此頂點及所有出邊。方案一,用鄰接矩陣來儲存圖,時間複雜度為 o n n 因為 簡單就不貼出...