強連通分量就是有向圖中任意兩點可以互相到達的點構成的連通分量,演算法很多,簡單易懂的tarjan提出的scc演算法的核心思路就是:乙個點的後代出現能連到的最早的點就是自身時,這個點便和這些後代構成了強連通圖,具體的實現和割點或者雙連通的演算法都是很相似的,核心部分都是有dfs實現的。
題目描述:在有向圖裡找最大的結點集,使得結點集內的任意兩點可以至少單向連通。
1.首先,對於強連通分量裡的任意兩點都是可以互相到達的,所以我們只需要找一條單向路徑把盡量多的強連通分量串起來,就能得到最大的結點集。
2.具體做法就是找出所有強連通塊,然後縮點,將圖轉變成一張無環有向圖,每個點的權值就是該點代表的連通塊內點的數量,我們就要找出一條權值和最大的路徑,使用dp求解,dp[i]表示以連通塊i為起點最大權值和路徑的權值。
#include
#include
#include
#include
#include
#include
using
namespace
std;
const
int maxn=1005;
int n,m;
int sccno[maxn];
int pre[maxn];
int lowl[maxn];
bool
map[maxn][maxn];
bool v[maxn];
int val[maxn];
int ans=0;
int dp[maxn];
vector
e[maxn];
int dfs_clock,scc_cnt;
stack
s;void dfs(int u)
else
if(!sccno[v])
}if(lowl[u]==pre[u])
}}void find_scc(int n)
}int dp(int cnt)
ans=max(ans,dp[cnt]);
}int main()
find_scc(n);
for(int i=0;ifor(int i=0;ifor(int j=0;jif(sccno[i]==sccno[e[i][j]])continue;
map[sccno[i]][sccno[e[i][j]]]=1;}}
for(int i=1;i<=scc_cnt;i++)
for(int i=1;i<=scc_cnt;i++)
}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演算法求強連通分量。define n 1000 struct edge e 100000 int ec,p...
強連通分量
在有向圖g中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強連通 strongly connected 如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。非強連通圖有向圖的極大強連通子圖,稱為強連通分量 strongly connected components 下圖中,子圖為乙個強連通分量,因為...