乙個
n n
個節點,
m' role="presentation" style="position: relative;">m
m條邊的單向圖,求是不是強連通。 1≤
n≤10000
1 ≤n
≤10000
1≤m≤100000
1 ≤m
≤100000
一張強連通圖的定義是任意兩個節點都可以互相到達。這裡使用**量短,流程清晰的 ta
rjan
t ar
ja
n演算法,具體流程如下。
void tarjan(int u)
else
if(!bel[v])low[u]=min(low[u],dfn[v]); //在棧裡的點
}if(dfn[u]==low[u]) //找到乙個強連通分量
}
最難理解的是 lo
w low
陣列。它的含義是子樹中通過一條反祖邊能到達 df
s dfs
序最小的點的編號。通過維護這個陣列,就能最大範圍的找到一塊強連通塊並記錄。其中 df
n,be
l dfn
,bel
陣列要保證初值為
0 0
,b,ord,
tp' role="presentation" style="position: relative;">b,o
rd,t
pb,o
rd,t
p的值顯然也要賦為零。
#include
#include
#include
#include
#include
#include
#include
#define for(i,x,y) for(int i=(x);i<=(y);i++)
#define dor(i,x,y) for(int i=(x);i>=(y);i--)
#define lowbit(x) ((x)&-(x))
#define n 100003
typedef
long
long ll;
using
namespace
std;
template
int maxn,const
int maxm>struct linked_list
void add(int u,int v)
#define eor(i,g,u) for(int i=g.head[u];~i;i=g.nxt[i])
};linked_listg;
stack
stk;
int dfn[n],belong[n],low[n],ord,ans,bcnt,n,m;
void tarjan(int u)
else
if(!belong[v])
low[u]=min(low[u],dfn[v]);
}if(dfn[u]==low[u])
while(u!=v);
ans=max(ans,cnt);
}}void clear()
int main()
for(i,1,n)if(!dfn[i])tarjan(i);
printf(ans==n?"yes\n":"no\n");
}return
0;}
HDU 1269 迷宮城堡
強連通分量,這題幾乎沒有除錯就ac了。第一次寫tarjan,真順利,其實可以再優化的,只要求出兩個以上的強連通分量就可以直接輸出no了,而不用再繼續算下去 include include include include include include include includeusing nam...
HDU 1269 迷宮城堡
為了訓練小希的方向感,gardon建立了一座大城堡,裡面有n個房間 n 10000 和m條通道 m 100000 每個通道都是單向的,就是說若稱某通道連通了a房間和b房間,只說明可以通過這個通道由a房間到達b房間,但並不說明通過它可以由b房間到達a房間。gardon需要請你寫個程式確認一下是否任意兩...
hdu 1269 迷宮城堡
根據題意,容易看出,這道題就是要求判斷該圖是否強連通,即只有乙個強連通分量,這樣的話,我們直接對圖運用tarjan演算法,求出圖中強連通分量的個數,只有乙個強連通分量就說明該圖強連通,否則該圖不強連通。這道題算是tarjan 的模板題 include include include include ...