/*
luogu p3387
縮點(強連通分量)+dagdp
by sbn
2018-2-11
algorithm:kosaraju
*/#include#include#include#include#include#include#include#includeusing namespace std;
const int maxn=1e5+11;
struct node
node(int nx,int ny,int nnxt)
}e[maxn*4],f[maxn*4],s[maxn*4];
// e:原圖 f:逆向圖 s:縮點後的圖
int cnt,head[maxn],headf[maxn],cntf,cnts,heads[maxn],dp[maxn];
//cnt?和head?配套圖使用
//dp表示從起點到這個點最大值
int rec[maxn],size,rd[maxn]=,w[maxn],cd[maxn];
//rec是dfs逆向圖生成的dfs序列(見kosaraju演算法)
//size是序列大小
//rd,cd是縮點後各點的入度,出度
//w是原圖中各個點的權值
int ds[maxn];
//ds是縮點後各個強連通分量的各點權值之和
bool vis[maxn];
//各種搜尋用的標記
inline void link(int x,int y)
int n,m,a,b,ans[maxn],len[maxn],q,num,ptd[maxn];
//n是點的個數,m是邊的個數,a,b是用於讀入時的點
/*len,ans用於存生成的縮點
例如ans:1,2,3,4,5,6
len:0,3,6
表示123,456是兩強連通分量
*/ // q是dfs時的臨時操作,表示ans下標
//num是強連通分量的個數
//ptd是每個點對應的強連通分量是誰
void dfsf(int u)
//dfs逆序圖,生成rec
void dfs(int u)
//dfs正序圖,生成ans,len
inline void link_d(int x,int y)
//縮點後的鏈結
inline void build()
}//縮點後建圖
void bfs(int u) }}
//dagdp部分,寬搜記憶化搜尋
int main()
memset(vis,0,sizeof(vis));
for (int j=1;j<=n;j++)
if (!vis[j]) dfsf(j);//生成rec
memset(vis,0,sizeof(vis));
for (int j=size;j>=1;j--)
if (!vis[rec[j]]) //縮點完畢
//cout
for (int i=1;i<=num;i++)
for (int j=len[i]+1;j<=len[i+1];j++)
ds[i]+=w[ans[j]];
build(); //統計個縮點的權值和建圖
for (int i=1;i<=num;i++)
dp[i]=ds[i];
memset(vis,0,sizeof(vis));
for (int j=1;j<=num;j++)
if (rd[j]==0)
bfs(j); //dp
int maxn=0;
for (int i=1;i<=num;i++)
maxn=max(dp[i],maxn);
cout
}
強連通分量 洛谷2818
本次專題是強連通分量的tarjan演算法,以下程式包含stl建圖,dfs遍歷,強連通分量假縮點,求縮點入度出度。include include include include include define m 10005 using namespace std stack s int pre m d...
強連通分量(模板)
low u min edge maxm 2 int head maxm 2 tot int low maxn dfn maxn belong maxn belong 的值為1 scc int index,top int scc 強連通分量 bool instack maxn int num maxn...
強連通分量模板
知識背景 首先明確強連通分量 strongly connected component 的概念,從任一頂點能夠到達任一其他頂點的有向圖 的頂點子集,而任意有向圖均可以分解成若干不相交的scc。把每個scc視作乙個頂點,可得到乙個dag。實現演算法 兩次dfs,第一次 dfs 遍歷將頂點後序 post...