給定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...