強連通分量 tarjan

2021-08-09 23:49:49 字數 3349 閱讀 8380

洛谷 p2812 校園網路

洛谷 p3387 縮點

#include

#include

#include

#include

#include

using

namespace

std;

struct arrbot[1100000],d[1100000];

int head[20000],h[20000],stack[20000],low[20000],dfn[20000],bl[20000];

int rd[20000],cd[20000],tot,cnt,pos,top,scc,size[20000],n;

bool instack[20000];

inline

int read()

inline

void add(int a,int b)

inline

void ad1(int a,int b)

inline

void tarjan(int u)

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

}}int main()}

for(register

int i=1;i<=n;++i) if(!dfn[i])tarjan(i);

tot=0;

for(register

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

for(register

int j=head[i];j;j=bot[j].nx)

int ans1=0,ans2=0;

for(register

int i=1;i<=scc;++i)

if(scc==1) printf("1\n0");

else

printf("%d\n%d",ans1,max(ans1,ans2));

}

一道模板題,就直接貼**了。

下面這份**是先tarjan縮點,再建立乙個新圖,然後加上spfa

#include

#include

#include

#include

#include

#include

using

namespace

std;

struct arrbot[1100000],d[1100000];

int head[100000],h[100000],stack[100000],low[100000],dfn[100000],bl[100000];

int tot,cnt,pos,top,scc,m,n;

int c[100000],w[100000];

long

long dist[100000],f[100000];

long

long ans;

bool instack[100000];

inline

int read()

inline

void add(int a,int b)

inline

void ad1(int a,int b)

inline

void tarjan(int u)

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

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

}}inline

void spfa(int s)}}

}for(register

int i=1;i<=scc;++i) if(ansint main()

for(register

int i=1;i<=n;++i) if(!dfn[i]) tarjan(i);

for(register

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

for(register

int j=head[i];j;j=bot[j].nx)

for(register

int i=1;i<=scc;++i) spfa(i);

//對於縮點後新建的圖跑spfa

printf("%d\n",ans);

}

下面這個**是先tarjan縮點,建立乙個新圖,然後加上拓撲排序求最長路。

(本蒟一開始做的時候只有40分,後面請了機房某xxy大佬幫我改了下才過的)

#include

#include

#include

#include

#include

#include

using

namespace

std;

struct arrbot[210000],d[210000];

int head[20000],a[20000],h[20000];

int rd[20000],cd[20000],dis[20000],topo[30000];

int low[20000],dfn[20000],stack[20000],instack[20000],bl[20000],size[20000],c[20000];

int n,m,cnt,tot,tt,top,pos,scc,ans;

inline

int read()

inline

void add(int a,int b)

inline

void ad1(int a,int b)

inline

void tarjan(int u)

if(instack[v])

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

}}inline

void tuopu()

}for(register

int i=1;i<=scc;++i) dis[i]=c[i];

int ans=0;

for(int k=1;k<=tt;++k)

}for(register

int i=1;i<=scc;++i) ans=max(ans,dis[i]);

printf("%d\n",ans);

}int main()

for(register

int i=1;i<=n;++i)if(!dfn[i]) tarjan(i);

for(register

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

for(register

int j=head[i];j;j=bot[j].nx) //建立新圖的時候要注意加入的點是bl[i]和bl[v],不是i和v,錯了好幾次

}tuopu();

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

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 ...

強連通分量 tarjan

題1 p2002 訊息擴散 題目描述 有n個城市,中間有單向道路連線,訊息會沿著道路擴散,現在給出n個城市及其之間的道路,問至少需要在幾個城市發布訊息才能讓這所有n個城市都得到訊息。輸入輸出格式 輸入格式 第一行兩個整數n,m表示n個城市,m條單向道路。以下m行,每行兩個整數b,e表示有一條從b到e...