求割点和点双连通分量
const int maxn = 1010;
vector <int> a[maxn], bcc[maxn];
int pre[maxn];
int low[maxn];
bool iscut[maxn];
int bccno[maxn];
int cnt[maxn];
int dfs_clock;
int bcc_cnt;
int n;
struct Edge
{
int u, v;
};
stack <Edge> S;
int dfs(int u, int fa)
{
int lowu = pre[u] = ++dfs_clock;
int child = 0;
for(int i = 0; i < a[u].size(); i++)
{
int v = a[u][i];
Edge e = (Edge){u, v};
if(!pre[v])
{
S.push(e);
child++;
int lowv = dfs(v, u);
lowu = min(lowu, lowv);
if(lowv >= pre[u])
{
iscut[u] = true;
bcc_cnt++;
bcc[bcc_cnt].clear();
cnt[u]++;
while(1)
{
Edge x = S.top();
S.pop();
if(bccno[x.u] != bcc_cnt)
{
bcc[bcc_cnt].push_back(x.u);
bccno[x.u] = bcc_cnt;
}
if(bccno[x.v] != bcc_cnt)
{
bcc[bcc_cnt].push_back(x.v);
bccno[x.v] = bcc_cnt;
}
if(x.u == u && x.v == v)
break;
}
}
}
else if(pre[v] < pre[u] && v != fa)
{
S.push(e);
lowu = min(lowu, pre[v]);
}
}
if(fa < 0 && child == 1)
{
iscut[u] = false;
cnt[u] = 0;
}
if(fa < 0 && child > 1)
{
iscut[u] = true;
cnt[u] = child;
}
else if(cnt[u] > 0)
cnt[u]++;
return lowu;
}
void find_bcc()
{
memset(cnt, 0, sizeof(cnt));
memset(pre, 0, sizeof(pre));
memset(iscut, 0, sizeof(iscut));
memset(bccno, 0, sizeof(bccno));
dfs_clock = bcc_cnt = 0;
dfs(1, -1);
}
求桥和双连通
#include <cstdio>
#include <cstring>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;
const int maxn = 5010;
vector <int> G[maxn];
bool ok[maxn][maxn];
int pre[maxn];
int low[maxn];
int sccno[maxn];
int dfs_clock;
int scc_cnt;
stack <int> S;
int n, m;
int degree[maxn];
int Topo[maxn][maxn];
void dfs(int u, int fa)
{
pre[u] = low[u] = ++dfs_clock;
S.push(u);
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(v == fa)
continue;
if(!pre[v])
{
dfs(v, u);
low[u] = min(low[u], low[v]);
}
else
low[u] = min(low[u], pre[v]);
}
if(low[u] == pre[u])
{
scc_cnt++;
while(1)
{
int x = S.top();
S.pop();
sccno[x] = scc_cnt;
if(x == u)
break;
}
}
}
void find_scc()
{
dfs_clock = scc_cnt = 0;
memset(sccno, 0, sizeof(sccno));
memset(pre, 0, sizeof(pre));
for(int i = 1; i <= n; i++)
if(!pre[i])
dfs(i, -1);
}
const int maxn = 10010;
struct Edge
{
int u, v;
Edge(){}
Edge(int u, int v): u(u), v(v){}
};
vector <int> a[maxn];
int pre[maxn];
int low[maxn];
int bccno[maxn];
Edge cnt[maxn];
int dfs_clock;
int bcc_cnt;
int bri;
int n, m;
stack <Edge> S;
bool cmp(Edge a, Edge b)
{
if(a.u != b.u)
return a.u < b.u;
return a.v < b.v;
}
void dfs(int u, int fa)
{
low[u] = pre[u] = ++dfs_clock;
for(int i = 0; i < a[u].size(); i++)
{
int v = a[u][i];
//if(v == fa)
// continue;
if(!pre[v])
{
dfs(v, u);
low[u] = min(low[u], low[v]);
if(low[v] > pre[u])
{
if(u < v)
{
cnt[bri].u = u;
cnt[bri].v = v;
}
else
{
cnt[bri].u = v;
cnt[bri].v = u;
}
bri++;
}
}
else if(v != fa)
low[u] = min(low[u], pre[v]);
}
}
void find_bcc()
{
memset(pre, 0, sizeof(pre));
memset(bccno, 0, sizeof(bccno));
dfs_clock = bcc_cnt = bri = 0;
for(int i = 0; i < n; i++)
if(!pre[i])
dfs(i, -1);
}