拓撲排序(例B 貓貓向前衝

2021-10-05 03:43:13 字數 3233 閱讀 1322

●將入度為0的點組成一-個集合s

●每次從s裡面取出乙個頂點u (可 以隨便取)放入l,然後遍歷頂點u的所有邊(u,v),並刪除之,並判斷如果該邊的另乙個頂點v,如果在移除這一條邊**度為0,那麼就將這個頂點放入集合s中。不斷地重複取出頂點然後重複這個過程…

●最後當集合為空後,就檢查圖中是否存在任何邊。如果有,那麼這個圖一定有環路,否者返回l,l中順序就是拓撲排序的結果.

以下模板是參考該部落格,留作筆記。

kahn模板

//kahn演算法,關鍵在於需要維護乙個入度為0的頂點的集合

int n,m;

int indeg[n]

;//i點的入度

vector<

int>vec[n]

;//i點的鄰接表,即i與哪些點相連

int ans[n]

;//排序結果陣列

inttopsort()

//返回值代表是否有環,排序結果在ans陣列

}return

(cnt==n)?1

:0;//是否等於n,等於n代表無環

}void

init()

//輸入資料,n個點,m條邊

}

dfs模板

//dfs實現,從出度的角度來構造,遞迴到最後返回

int n,m;

vector<

int>vec[n]

;//i點的鄰接表,即i與哪些點相連

int ans[n]

,cnt;

//排序結果陣列,cnt記錄個數

int parent[n]

;//記錄其前置節點

//int d[n], time, f[n];

//可以不要,時間time初始化為0,d記錄第一次被發現時,f記錄結束檢查時

int vis[n]

;//標記陣列vis[i]=0表示還未訪問過點i,c[i]=1表示已經訪問過點i,

//並且還遞迴訪問過它的所有子孫,c[i]=-1表示正在訪問中,尚未返回

bool

dfs(

int s)

//深度優先搜尋(鄰接表實現),記錄時間戳,尋找最短路徑

vis[s]=1

;//time++;f[s]=time;

ans[cnt++

]=s;

//結果是逆序的,遞迴的原因

return

true;}

bool

topsort()

//返回值代表是否有環,排序結果在ans陣列

//time=0;

for(

int i=

1;i<=n;i++)if

(!vis[i])if

(dfs

(i)==

false

)return

false

;return

true;}

void

init()

//輸入資料,n個點,m條邊

}

眾所周知, tt 是一位重度愛貓人士,他有乙隻神奇的魔法貓。

有一天,tt 在 b 站上**貓貓的比賽。一共有 n 只貓貓,編號依次為1,2,3,…,n進行比賽。比賽結束後,up 主會為所有的貓貓從前到後依次排名並發放愛吃的小魚幹。不幸的是,此時 tt 的電子裝置遭到了宇宙射線的降智打擊,一下子都連不上網了,自然也看不到最後的頒獎典禮。

不幸中的萬幸,tt 的魔法貓將每場比賽的結果都記錄了下來,現在他想程式設計序確定字典序最小的名次序列,請你幫幫他。

input

輸入有若干組,每組中的第一行為二個數n(1<=n<=500),m;其中n表示貓貓的個數,m表示接著有m行的輸入資料。接下來的m行資料中,每行也有兩個整數p1,p2表示即編號為 p1 的貓貓贏了編號為 p2 的貓貓。

output

給出乙個符合要求的排名。輸出時貓貓的編號之間有空格,最後一名後面沒有空格!

其他說明:符合條件的排名可能不是唯一的,此時要求輸出時編號小的隊伍在前;輸入資料保證是正確的,即輸入資料確保一定能有乙個符合要求的排名。

sample input

431

2234

3

output

1 2 4 3

提取題目資訊:

n個點,m個關係,其實關係是滿足傳遞閉包的

a戰勝b b戰勝c, 那麼a一定可以戰勝c,對於勝負關係不確定的,就採用編號

從小到大排列,也就是符合拓撲排序條件,下面我用kahn演算法寫的

#include

#include

#include

#include

using

namespace std;

const

int maxn=

1010

;priority_queue<

int,vector<

int>

,greater<

int>

> pq;

//小根堆

vector<

int> q;

//容器

int head[maxn]

,in_deg[maxn]

,tot,n,m,p1,p2;

//n為點數,m為邊數

struct edge

;edge e[maxn*2]

;void

init()

while

(!pq.

empty()

) pq.

pop();

q.clear()

;tot=0;

}void

add_edge

(int u,

int v,

int w)

void

toposort()

}for

(int i=

0;i) cout<

}int

main()

toposort()

;}return0;

}

B 貓貓向前衝(拓撲排序

輸入有若干組,每組中的第一行為二個數n 1 n 500 m 其中n表示貓貓的個數,m表示接著有m行的輸入資料。接下來的m行資料中,每行也有兩個整數p1,p2表示即編號為 p1 的貓貓贏了編號為 p2 的貓貓。給出乙個符合要求的字典序最小的排名。輸出時貓貓的編號之間有空格,最後一名後面沒有空格 樣例 ...

B貓貓向前衝 拓撲排序

給出乙個有向無環圖,拓撲排序的目標是將所有節點排序,使得排在前面的節點不能依賴於排在後面的節點。kahn演算法 將入度為0的點組成乙個集合s 每次從s裡面取出乙個頂點u 可以隨便取 放入l,然後遍歷頂點u的 所有邊 u,v 並將所有的v入度 1 如果入度更新之後是0,那麼就將這個頂點放入集合s中。不...

拓撲排序 貓貓向前衝

眾所周知,tt 是一位重度愛貓人士,他有乙隻神奇的魔法貓。有一天,tt 在 b 站上 貓貓的比賽。一共有 n 只貓貓,編號依次為1,2,3,n進行比賽。比賽結束後,up 主會為所有的貓貓從前到後依次排名並發放愛吃的小魚幹。不幸的是,此時 tt 的電子裝置遭到了宇宙射線的降智打擊,一下子都連不上網了,...