Swapping Places 拓撲排序 詳解

2021-10-08 03:52:23 字數 1595 閱讀 8090

給定s種動物, l對朋友關係, n個動物, 如果兩個相鄰的動物是朋友關係, 則可以換序. 讓你給n個動物排序, 希望盡可能按照字典序輸出所有動物

拓撲排序, 由於兩個不是朋友關係(或者為同種動物)的兩個動物的前後相對位置是不會改變的(即 後面的動物不會排序到前面這個動物的前面). 所以我們可以以此約束建立拓撲圖. 遍歷每乙個位置, 觀察前面出現的動物有沒有對當前動物產生約束的. 但這樣的複雜度為o(n2).

優化: 其實我們每次只需要在當前位置遍歷所有動物種類就可以了, 如果前面出現了多次某種動物, 沒有必要都對當前動物建立約束(邊), 因為同種動物自身也有約束, 例如ant ant, 如果前面的ant不被排好序, 則其對後面ant的約束是會一直存在的, 則後面ant對其後其餘位置的約束也會一直存在.

利用這個思路, 我們幾番折騰可以完成排序!

#include

typedef

long

long ll;

using

namespace std;

const

int n =

1e5+10;

bool g[

205]

[205];

//記錄兩個物種間是否存在關係

vector<

int> edge[n]

;int du[n]

;//表示入度

vector

name(1

);//建立對映, 由編號得出名字 int->string

unordered_mapint> m;

//建立對映, 由名字得出編號 string->int

int a[n]

, last[

205]

;//a表示當前位置的物種, last表示某物種最後出現的位置

setint,

int>> st;

//排序

int s, l, n;

void

init()

sort

(name.

begin()

, name.

end())

;int id =-1

;//下標是從1開始的, vecotr初始化時存入了乙個0

for(

auto

& i : name) m[i]

=++id;

/* 存關係 */

while

(l--)}

void

topo()

);}int cou =0;

//完成排序的數量

while

(!st.

empty()

));}

}}intmain

(void

) last[op]

= i;

}/* 排序 */

topo()

;return0;

}

關於拓撲排序的理解: 按照邊(點)對點的約束進行排序, 乙個點的入度越大, 表明對其約束的邊就越多, 則該點應在所有對其有約束的點都確定好順序後才能排序.

拓拔排序演算法

一 定義 拓撲排序是對有向無迴路圖 dag 頂點的一種排序,它使得如果存在從u到v的有向路徑,那麼滿足序列中u在v前。例如 來自於某牛 最後變成 所以我們的演算法可以描述為這樣乙個過程 1 找到整個圖中所有的原點,將這些點壓進佇列 棧 中 2 從佇列 棧 中取出一點,輸出,將該點及它的邊刪除,找到它...

拓普排序介紹

拓撲排序 topological order 是指,將乙個有向無環圖 directed acyclic graph簡稱dag 進行排序進而得到乙個有序的線性序列。這樣說,可能理解起來比較抽象。下面通過簡單的例子進行說明!例如,乙個專案包括a b c d四個子部分來完成,並且a依賴於b和d,c依賴於d...

2014 10 31天拓遊戲筆試總結

package test public class testa static package test class testb extends testa static package test public class test 執行結果 a靜態 塊 b靜態 塊 a class a構造b clas...