//p2002解題思路:
//先求scc,縮點後,轉換為dag(有向無環圖)
//在dag上統計入度為0的scc數量即可
//tarjan時間複雜度:o(n+e),每個點和每條邊剛好被訪問一次,在空間和時間上比kosaraju好一些。
#include#include#include#includeusing namespace std;
const int maxn=500010;
struct edge };
edge * h[maxn]; //h2是反圖
void add(int u, int v)
int n, m, v[maxn], st[maxn], st_k, dfn[maxn], low[maxn], timestamp, sccno[maxn], scc_cnt, scc_indegree[maxn];
void tarjan(int x)
if(dfn[x]==low[x]) //發現scc
v[st[st_k--]]=0; //取消x在堆疊中的標記
} }int main()
for(int i=1; i<=n; i++) if(!dfn[i]) tarjan(i);
for(int i=1; i<=n; i++) //統計每個scc的入度
for(edge *p=h[i]; p; p=p->nxt)
if(sccno[i]!=sccno[p->t]) scc_indegree[sccno[p->t]]++; //起點和終點不在乙個scc中才統計入度
int ans=0;
for(int i=1; i<=scc_cnt; i++) if(!scc_indegree[i]) ans++; //統計入度為0的scc的個數
printf("%d\n", ans);
return 0;
}
強連通分量 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 ...