close

這題運用到拓璞排序(Topological Sort)

基本上,拓璞排序使用的是有向圖 (也就是圖的每個邊都是有方向性的)

像是這樣子的一個有向圖:
        A → B → C
                     ↗
                 D

拓璞排序,基本的原則就是每次皆取出無其他元素指向該元素的元素
以上圖來說,我們就可以先取出A跟D
已排序隊伍:[A D]  //AD的順序則是隨意,看有沒有規定


此時圖便只剩下
        B → C
這時B沒有其他元素指向,故取出
已排序隊伍:[A D B]

最後只剩下C,也無人其他元素指向,取出,結束。
已排序隊伍:[A D B C]

所以拓璞排序的結果就是A D B C。


至於有向邊的紀錄,屬於圖論的基本範疇
這邊可以用到的方法有兩種,一種稱為鄰接矩陣(adjacent matrix)
也就是拿二維陣列紀錄兩點之間有無連線。
另一種稱為鄰接串列(adjacent list)
即是拿鏈結串列來實現上面的圖。
前者在元素少時(我們稱之為稀疏 sparse)效率低落,但可以很快知道兩者之間是否有連接
後者則剛好相反。

而拓璞排序通常用在排程,比如說b工作要等a工作做完才能做
那麼找出一個合法的順序,b就不能在a前面

另一種說明例子by sa

    學BFS前要先學過queue和Graph的資結,所以,就不可以把BFS排在queue
    和graph的資結前面,可是queue和graph的資結兩者不相關,所以先後就比較沒關係。
    以上面那個圖來講,可以看成A是[queue] D是[graph] B是[BFS] C是[AC掉ACM532]。



這題基本上就是先經過文字處理
每兩組比較一次(有n組就會比較n-1次)
比較就是兩兩逐字比較,找到不相同的便記錄、跳出
並記錄有多少元素
最後再慢慢砍掉,直到所有元素砍完為止。



sa再曰:

[Part I]
    使用拓璞排序時,我們可以記錄每個點有多少點指向它,如此一來,找沒人指向它的
    點時,便可以只比較一次就好。
    而每次砍點的時候,我們可以把它有指向的點的點紀錄的個數-1。

[Part II]
    砍點的時候,如果總共有1000個點,但某個點只指向幾個點,那麼便是稀疏的情形了
    這種時候用adjacent list會較快、較有效率。
    又因為上面提到的方式可以使用adjacent list,所以我們可以直接使用adjacent。

[Part III]
    每次要找的是沒人指向的點,也就是記錄為0的點,這時也是最小值。所以我們可以
    使用min-heap,內部的操作則是使用到了priority queue的提高優先度。
    基本上就是砍掉點後某些點的值會減少,而我們要對這些點作向上調整。
    (某些點就是砍掉那點有指向的點)

[Part IV]
    如果只用adjacent list時,如果題目一直告訴你z→y,那麼你的list可能會長到很長
    但是事實上只需要一個z→y,所以我們便可以將adjacent matrix在這裡並用,
    記錄某個邊是否有出現過。
    也就是我們可以利用adjacent matrix擋重複,用adjacent list加速運算。

大致如此′▽`)
arrow
arrow
    全站熱搜

    aikosenoo 發表在 痞客邦 留言(0) 人氣()