# 這是乙個漫(jian)長(nan)的過程
請大家耐心讀完,相信你一定能學會
首先來介紹一下強連通分量
神奇海螺指引你:
tarjan是基於迪法師(dfs)的一種演算法,可以說是一種流(du)批(liu)的操作,本蒟蒻苦哈哈的學了好幾天才學會強連通分量和縮點;
步入正軌:
圖中{6}是第乙個被發現的強連通分量,其次是{5},最後被發現的是{3,4,1,2}(順序無所謂)
tarjan演算法是解決強連通分量和縮點問題的一種比較常見的方法
接下來開始一步一步的
首先給你乙個圖(求其中的強連通分量)
在這裡我們假設從點1開始遍歷,並且將訪問的點壓入棧中
在進行操作之前,我們要明確tarjan中的兩個至關重要的陣列:dfn和low;
dfn[x]:表示這個點x幾次被遍歷到;
low[x]:表示點x或點x的子樹能夠追溯到的最早的棧中節點的次序號;
即low[x]=min;
其中next為x的子節點;
接下來,我們來一步一步的找;
第一遍從1直接一直遍歷到6,另訪問到的點的初始low和dfn都為num++;num為計數器;
但當我們遍歷到6是發現6沒有子節點了,所以low[6]=dfn[6]=4;發現乙個強連通分量{6},6出棧;
退回到5,low[5]=min(low[5],low[6]);
low[6]=4;而low[5]=dfn[5]=3;
所以low[5]=3;
low[5]=dfn[5];所以5也是乙個強連通分量;5出棧;
返回3發現3有子節點4,搜尋4,並且4入棧;發現4也有子節點,6已經為強連通分量且不再棧中,跳過;
遍歷1,發現一在棧中且已經被訪問過,那麼4值得被發現;
所以low[4]=min(low[4],dfn[1]);所以low[4]=1;
4遍歷完,又因為dfn[4]!=low[4],所以4不退站;回到3,low[3]=min(low[3],low[4]);
所以low[3]=1;3訪問完,又因為dfn[3]!=low[3],所以3不退站;
回到1,發現1還有子節點2,2入棧;發現2的子節點4已經被訪問且在棧中,所以low[2]=min(dfn[4],low[2]);
所以low[2]=5;訪問完2,回到一,發現low[1]=dfn[1];所以將棧中的所有點出棧,並且這些點為乙個強連通分量;
至此,所有點已經都被訪問,演算法結束。
時間複雜度為o(n+m);
下面插上**:
#include#include#include#include#include#define size 101接下來,講一下縮點,using namespacestd;
inline intread()
while(ch>='0'&&ch<='9')
return x*f;
}stackatack;
vectormap[size];
int a,b,c,d,num=0,low[size],dfn[size];
boolinst[size];
void tarjan(intnow)
else if(inst[next]==1)
}if(dfn[now]==low[now])
while(p!=now);
cout<
}}intmain()
memset(dfn,0,sizeof(dfn));
memset(inst,false,sizeof(inst));
for(int i=1;i<=a;++i)
return 0;
}
縮點基於強連通分量,在強連通分量的基礎上,稍微加一些操作即可。
縮點就是將所有在同乙個強連通分量中的點,壓進乙個點,然後再累加起每個點的權值,再每個點進行判斷,看他們所屬的強連通分量是否相同,如果不相同,則說明就是兩個不同的縮玩以後的點,我們就可以將他們存起來,存入乙個新圖。就是縮玩點以後的圖。
void tarjan(intnow)else if(inst[next]==1)
}if(dfn[now]==low[now])
while(q!=now);}}
for(int i=1;i<=a;i++)}}
強連通分量 tarjan求強連通分量
雙dfs方法就是正dfs掃一遍,然後將邊反向dfs掃一遍。挑戰程式設計 上有說明。雙dfs 1 include 2 include 3 include 4 include 5 6using namespace std 7const int maxn 1e4 5 8 vector g maxn 圖的鄰...
強連通分量 tarjan
洛谷 p2812 校園網路 洛谷 p3387 縮點 include include include include include using namespace std struct arrbot 1100000 d 1100000 int head 20000 h 20000 stack 200...
強連通分量 tarjan
struct enodeedge maxm int p maxn ec void inserte int u,int v,int w int dfn maxn ctime,low maxn 時間戳,時間戳計數,祖先時間。int gid maxn gc 分量陣列,分量計數。bool ins maxn ...