强连通分量
int low[maxn],dfn[maxn];
int sta[maxn];//secondary stack in SCC
int point[maxn];//scc that vertices belong to
bool omit[maxn];//if the vertiex have been visited and poped from stack, omit=1
int top,times,tot;
void scc(int now)//strongly connectly component
{
times++;
dfn[now]=low[now]=times;
top++;
sta[top]=now;
omit[now]=0;
for (auto to:A[now])
{
if (!dfn[to])//have not been visited
{
scc(to);
low[now]=min(low[now],low[to]);//update low,maybe our son have discovered a whole new world
}
else if (!omit[to])
{
low[now]=min(low[now],dfn[to]);//yes i have discovered a whole new world
}
}
if (low[now]==dfn[now])//finally,i came full circle
{
tot++;
do
{
// totalval[tot]+=val[sta[top]];
point[sta[top]]=tot;
omit[sta[top]]=1;
top--;
}
while (sta[top+1]!=now);
}
}
//init FOR(i,1,2*n+5) low[i] = dfn[i] = omit[i] = sta[i] = point[i] = 0;
双联通分量
#include <bits/stdc++.h>
#pragma GCC diagnostic error "-std=c++11"
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
//#define endl '
'
#define all(A) (A).begin(),(A).end()
#define FOR(I, A, B) for (int I = (A); I <= (B); ++I)
#define PER(I, A, B) for (int I = (A); I >= (B); --I)
#define lson k*2
#define rson k*2+1
#define fi first
#define se second
#define DB(A) cout<<(A)<<endl
#define DB1(A,B,C) cout<<(A)<<" "<<(B)<<" "<<(C)<<"!"<<endl
#define PB push_back
#define Pair pair<int,int>
#define MP make_pair
#define LL long long
using namespace std;
const int maxn=1000+10;
const int MAX=1000;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
//head
int n,m;
int low[maxn],dfn[maxn];
int sta[maxn];
int t,times,top,tot;
int isbridge[maxn];
int ne[maxn],u[maxn],v[maxn],fi[maxn];//forward_star
void edge(int x,int y)
{
t++;
ne[t]=fi[x];
fi[x]=t;
u[t]=x;
v[t]=y;
}
void bcc(int now,int fa)//biconnected component,求割点
{
times++;
dfn[now]=low[now]=times;
// top++;
// sta[top]=now;
// omit[now]=0;
for (int i=fi[now];i!=-1;i=ne[i])
{
if (!dfn[v[i]])//have not been visited
{
bcc(v[i],now);
if (low[v[i]]<low[now]) low[now]=low[v[i]];
if (dfn[now]>low[v[i]]) isbridge[i]=0,isbridge[i^1]=0;
//low[now]=min(low[now],low[v[i]]);//update low,maybe our son have discovered a whole new world
}
else if (v[i]!=fa)//if (!omit[v[i]])
{
if (dfn[v[i]]<low[now]) low[now]=dfn[v[i]];//yes i have discovered a whole new world
}
}
// if (low[now]==dfn[now])//finally,i came full circle
// {
// tot++;
// do
// {
// dis[tot]+=d[sta[top]];
// point[sta[top]]=tot;
// omit[sta[top]]=1;
// top--;
// }
// while (sta[top+1]!=now);
// }
}
int main()
{
scanf("%d%d",&n,&m);
t=-1;
top=0;
tot=0;
times=0;
// memset(dis,0,sizeof(dis));
// memset(dfn,0,sizeof(dfn));
// memset(num,0,sizeof(num));
for (int i=1;i<=n;i++) fi[i]=-1;
for (int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
edge(x,y);
edge(y,x);
}
for (int i=1;i<=m*2;i++) isbridge[i]=1;
for (int i=1;i<=n;i++)
if (!dfn[i]) bcc(i,0);
// FOR(i,0,m*2-1) if (isbridge[i]==1) return DB(0),0;
// dfs(1);
return 0;
}