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