hdu 3861 強量通分量 最小路徑覆蓋

2021-07-15 23:55:33 字數 2263 閱讀 9068

有向圖中,路徑覆蓋就是在圖中找一些路徑,使之覆蓋了圖中的所有頂點,且任何乙個頂點有且只有一條路徑與之關聯;(如果把這些路徑中的每條路徑從它的起始點走到它的終點,那麼恰好可以經過圖中的每個頂點一次且僅一次);如果不考慮圖中存在迴路,那麼每條路徑就是乙個弱連通子集.

對於乙個路徑覆蓋,有如下性質:

每個頂點屬於且只屬於乙個路徑。

路徑上除終點外,從每個頂點出發只有一條邊指向路徑上的另一頂點。

路徑覆蓋與二分圖匹配的關係(必須是有向無環圖):

最小路徑覆蓋=|p|-最大匹配數

其中最大匹配數的求法是把p中的每個頂點pi分成兩個頂點pi』與pi」,如果在p中存在一條pi到pj的邊,那麼在二分圖p』中就有一條連線pi』與pj」的無向邊;這裡pi』 就是p中pi的出邊,pj」就是p中pj 的一條入邊;

對於公式:最小路徑覆蓋=|p|-最大匹配數;可以這麼來理解;

如果匹配數為零,那麼p中不存在有向邊,於是顯然有:

最小路徑覆蓋=|p|-最大匹配數=|p|-0=|p|;即p的最小路徑覆蓋數為|p|;

p』中不在於匹配邊時,路徑覆蓋數為|p|;

如果在p』中增加一條匹配邊pi』-->pj」,那麼在圖p的路徑覆蓋中就存在一條由pi連線pj的邊,也就是說pi與pj 在一條路徑上,於是路徑覆蓋數就可以減少乙個;

如此繼續增加匹配邊,每增加一條,路徑覆蓋數就減少一條;直到匹配邊不能繼續增加時,路徑覆蓋數也不能再減少了,此時就有了前面的公式;但是這裡只 是說明了每條匹配邊對應於路徑覆蓋中的一條路徑上的一條連線兩個點之間的有向邊;下面來說明乙個路徑覆蓋中的每條連線兩個頂點之間的有向邊對應於一條匹配 邊;

與前面類似,對於路徑覆蓋中的每條連線兩個頂點之間的每條有向邊pi—>pj,我們可以在匹配圖中對應做一條連線pi』與pj」的邊, 顯然這樣做出來圖的是乙個匹配圖(這一點用反證法很容易證明,如果得到的圖不是乙個匹配圖,那麼這個圖中必定存在這樣兩條邊 pi』—pj」 及 pi』 —-pk」,(j!=k),那麼在路徑覆蓋圖中就存在了兩條邊pi–>pj, pi—>pk ,那邊從pi出發的路徑就不止一條了,這與路徑覆蓋圖是矛盾的;還有另外一種情況就是存在pi』—pj」,pk』—pj」,這種情況也類似可證);

把有向圖中,劃分為幾個區域,區域中u可以到v,或者v到u,但是路徑中沒有其他區域的點。經過劃分,求劃分區域最少的數目。

每個強連通分量中,任意兩個點,可以到達。所以可以將每個強連通分量縮點,之後就可以轉化為邊覆蓋問題,為了最少,求最小邊覆蓋就可以了。

#include 

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int inf=0x3f3f3f3f;

const

int maxn = 10000+100;

typedef

long

long ll;

int dfn[maxn], low[maxn];

stack

s;int scc_cnt;

int sccno[maxn];

int dfs_clock;

vector

g[maxn];

vector

g[maxn];

int match[maxn];

int vis[maxn];

void init()

void tarjan(int u)

else

if (!sccno[v])

low[u] = min(dfn[v], low[u]);

}if (dfn[u] == low[u])

}}int findpath(int u) }}

return0;}

int main()

for (int i=1; i<=n; i++)

for (int i=1; i<=scc_cnt; i++)

g[i].clear();

for (int i=1; i<=n; i++)}}

int res = 0;

for (int i=1; i<=scc_cnt; i++)

}printf("%d\n", scc_cnt-res);

}return

0;}

強連通 最小路徑覆蓋 hdu 3861

題意 有 n 座城市和 m 條有向邊,現在要把這 n 座城市分成一些洲,要求 如果城市 u,v 之間可以互達則兩座城市要分在乙個洲裡面,每個洲裡面的任意兩個城市 u,v之間至少需要存在一條邊,問做少能夠分成多少個洲。先將可以互相到達的點縮點,然後要求用最小的邊將點連線,所以是最小路徑覆蓋問題。inc...

hdu 4612 強連通分量

題意 有一些小島,這些小島上有一些邊,讓你加一條邊,使得原先的那些邊的橋數最少。做法 1,把小島為點,連線小島的為邊建圖。2,求出圖中的所有強聯通分量 3,把所有的強聯通分量看成乙個點建樹。4,求樹的直徑,新加的那條邊應該在直徑的兩邊,這樣才能使得圖中的橋最小。pragma comment link...

HDU 3072 強連通分量

題目鏈結 題目大意 為乙個有向連通圖加邊。使得整個圖全連通,有重邊出現。解題思路 先用tarjan把強連通分量縮點。由於整個圖肯定是連通的,所以列舉每一條邊,記錄到非0這個點所在連通分量的最小cost。一共需要累加cnt 1個連通分量的cost。在tarjan過程中的重邊,可以用鏈式前向星結構解決。...