#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long LL;
const int N=10010;
int h[N],e[N],nex[N],idx,n,m,root;
int low[N],dfn[N],id[N],timestamp;
int sk[N],top;
bool cut[N];
int dcc_cnt;
vector<int> dcc[N]; //存储每个点连通分量内的点
void add(int x,int y){
e[idx]=y;
nex[idx]=h[x];
h[x]=idx++;
}
void tarjan(int u){
dfn[u]=low[u]=++timestamp;
sk[top++]=u;
if(u==root&&h[u]==-1){
dcc_cnt++;
dcc[dcc_cnt].push_back(u);
}
int cnt=0;
for(int i=h[u];~i;i=nex[i]){
int v=e[i];
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
if(dfn[u]<=low[v]){
cnt++;
if(u!=root||cnt>1)
cut[u]=true;
++dcc_cnt;
int t;
do{
t=sk[--top];
dcc[dcc_cnt].push_back(t);
}while(v!=t);
dcc[dcc_cnt].push_back(u);//割点属于多个点连通分量,割点的数量可以作为点连通分量的度
}
}
else low[u]=min(low[u],dfn[v]);
}
}
int main(){
memset(h,-1,sizeof h);
cin>>n>>m;
while(m--){
int x,y;
cin>>x>>y;
add(x,y);
add(y,x);
}
for(root=1;root<=n;++root){
if(!dfn[root])
tarjan(root);
}
}
原文:https://www.cnblogs.com/jjl0229/p/12776076.html