Tarjan系列例題

2021-09-29 05:13:52 字數 3553 閱讀 1403

tarjan演算法——有向圖環問題的killer

洛谷模板題 題目

問節點大於1的強聯通分量個數

題解染色的**稍微修改即可

#include

#define maxl 400010

using

namespace std;

int n,k,ff,top,cnt,cnt2,id,num,m,m1,m2;

int a[maxl]

,b[maxl]

,s[maxl]

;int ehead[maxl]

,ehead2[maxl]

;struct ed

e[maxl]

,e2[maxl]

;int f[maxl]

,dfn[maxl]

,low[maxl]

;bool in[maxl]

;bool ansflag;

//鏈式前向星

inline

void

add(

int u,

int v)

inline

void

tarjan

(int u)

else

if(in[v]

&& dfn[v]

) low[u]

=dfn[v];}

if(dfn[u]

==low[u]

)while

(v!=u);}

}int

main()

for(

int i=

1;i<=n;i++

)int ans=0;

for(

int i=

1;i<=ff;i++

) cout<}

縮點模板題 題目

求有向圖中所有點都能到達的點

題解我們考慮加入圖中沒有環的情況,那麼出度為0的點就一定就是這個點,加入有兩個及以上出度為0的點,則這樣的點不存在,因為這幾個出度為0的點必不能互相到達

然後再考慮有環的情況,有環的情況比較複雜,但考慮到環內所有點的地位相同,作用相同,所以我們將每乙個環都縮成乙個點,這樣就能按照上述情況討論了(雖說是模板題,其實還是挺有難度的)

所謂的縮點實質在我看來就是先把乙個強聯通分量中的所有點染上同樣的顏色,然後遍歷每一條邊的時候只要邊的起點與終點點的顏色相同,就跳過這條邊,如果不同,就對兩個點的聯通分量的編號進行操作(而不是直接對兩個點進行操作),這樣就達成了縮點的目的

#include

#define maxl 400010

using

namespace std;

int n,k,ff,top,cnt,cnt2,id,num,m,m1,m2;

int a[maxl]

,b[maxl]

,s[maxl]

,du[maxl]

;int head[maxl]

,head2[maxl]

;struct ed

e[maxl]

,e2[maxl]

;int f[maxl]

,dfn[maxl]

,low[maxl]

;bool in[maxl]

;bool ansflag;

//鏈式前向星

inline

void

add(

int u,

int v)

inline

void

tarjan

(int u)

else

if(in[v]

&& dfn[v]

) low[u]

=dfn[v];}

if(dfn[u]

==low[u]

)while

(v!=u);}

}int

main()

for(

int i=

1;i<=n;i++

)for

(int i=

1;i<=n;i++)}

}int ans=

0,t=0;

for(

int i=

1;i<=ff;i++)}

}if(ans!=

1) cout<<

'0'

縮點應用題 題目

給出幾個節點的權值,詢問是否可以通過這幾個點遍歷到所有的點,如果可以問所需點權值的最小值,如果不可以輸出不能遍歷到的點的序號最小值

題解和上一題差不多吧,縮點後無環的有向圖,入度為0的點是不需要選取的點,只要入度為0的點取不了答案就是no,都取得了的話,就把所有點的權值相加就行(注意,縮點後點的權值為環中權值最小點的權值)

#include

#define maxl 400010

using

namespace std;

const

int m=

40000

;int n,k,ff,top,cnt,cnt2,id,num,m,m1,m2;

int a[maxl]

,b[maxl]

,s[maxl]

,v1[maxl]

,f1[maxl]

,du[maxl]

;int head[maxl]

,head2[maxl]

;struct ed

e[maxl]

,e2[maxl]

;int f[maxl]

,dfn[maxl]

,low[maxl]

;bool in[maxl]

;bool ansflag;

//鏈式前向星

inline

void

add(

int u,

int v)

inline

void

tarjan

(int u)

else

if(in[v]

&& dfn[v]

) low[u]

=dfn[v];}

if(dfn[u]

==low[u]

)while

(v!=u);}

}int

main()

cin>>m;

for(

int i=

1;i<=m;i++

)for

(int i=

1;i<=n;i++

)for

(int i=

1;i<=n;i++)}

int ans=0;

for(

int i=

1;i<=n;i++)}

}for

(int i=

1;i<=ff;i++

) cout<<

"yes\n"

}

tarjan系列各種連通分量總結

關於有向圖強連通分量的資料,我覺得最好的便是byvoid大牛的部落格 還有關於無向圖的雙聯通分量,橋,割點之類的了解一下概念就可以根據推出來的,就再推薦一篇部落格 另外還有一些我自己關於ssc的拙見 其實tarjan的作用主要就是縮點,其他的還是依靠圖論的知識來解決的 還是多做題,在題目中領會吧 h...

例題收藏 例題 V Gap

搜尋訓練開始了 poj的資料比zoj強多了!看來不得不寫正解了 傳送門 有乙個四行九列的矩陣 在第1 4行 2 8列上填上數字 11 17,21 27,31 37,41 47 不一定有序 例子如下 現在我們將數字11移動在第一行第一列,21移動在第二行第一列,31移動在第三行第一列,41移動在第四行...

tarjan演算法詳解

參考 tarjan演算法在強連通分量分離中運用很廣,書寫簡單,並且可以拓展到圖的割點,割邊上,十分強大 具體思路 令dfn u 表示當前點的時間戳 low u 表示當前點所能到達的點的時間戳中最小的乙個 到達點u時,將其入棧 拓展點u後代 當且僅當dfn u low u 時,棧頂元素全部出棧,此時出...