算法詳解之縮點

若圖片出問題請轉至[這兒]

前置技能:tarjan求強連通份量

縮點算法

顧名思義,就是在圖論算法中將一些點縮成一個點的一種算法。數組

  • 應用

貌似明白了,可是這有什麼用呢?code

咱們常常求最短路,可是若是咱們要求最長路呢?blog

標準問法:圖片

給你一張有向圖,每一個點都有一個點權(不是邊權了哦),且每個點均可以通過任意屢次,可是點權只能加一次,求這張圖的最大權值get

題目分析:io

看到這,相信大多數人都會想到把最短路的模板改一下就好了,可是這會出問題,你會在一個圈裏團團轉。模板

怎麼辦辦?class

咱們會發現,只要是一堆能夠構成強連通份量的點,咱們就能夠將它們縮成一個點,而這個點的點權就是它們的點權和,它的入邊就是它們全部點的入邊,出邊就是它們全部點的出邊。遍歷

放幾張圖有助於理解:

404

404

上圖中1.3.5就是一個強連通份量

  • 怎麼實現?

咱們在tarjan求強連通份量時開過一個數組叫作color[](或其餘名字)來記錄一個點 所屬於的強連通份量編號。因此咱們能夠遍歷每個點,看看它所能到達的點是否和它同處於同一個強連通份量中,若不是,則依託它們強連通份量的編號再構建一個有向無環圖 (想想,爲何要依託編號)

  • 代碼
for(int i=1;i<=n;i++)
    {
        for(int j=0;j<ver[i].size();j++)
        {
            int x=ver[i][j];
            if(color[i]!=color[x])
            {
                in[color[x]]++;
                g[color[i]].push_back(color[x]);
            }
        }
    }
    for(int i=1;i<=n;i++)
        ww[color[i]]+=w[i];//點權處理

這樣咱們就實現了縮點。

  • 題目:

[APIO2009]搶掠計劃

相關文章
相關標籤/搜索