void find(int father,int u)
{
int son=0,cnt=0;
dfn[u]=low[u]=++time;
for(int i=0;i<e[u].size();i++)
{
int v=e[u][i];
if(v==father&&cnt==0) //不在使用之前用过的边
{
cnt++;
continue;
}
if(dfn[v]==-1)
{
son++; //记录子树个数
find(u,v);
low[u]=min(low[v],low[u]);
if(father==0&&son>1) //如果是头结点并且子树不止一个则该点是割点
{
cut[u]=1;
}
if(father!=0&&dfn[u]<=low[v]) //如果不是头结点,并且子节点v无法遍历到u的父节点,则说明u为割点
{
cut[u]=1;
}
}
else
{
low[u]=min(dfn[v],low[u]);
}
}
}
int cut_point_sum()
{
int res=0;
time=0;
memset(dfn,-1,sizeof(dfn));
memset(cut,-1,sizeof(cut));
for(int i=1;i<=n;i++)
{
if(dfn[i]==-1)
{
find(0,i);
}
}
for(int i=1;i<=n;i++)
{
if(cut[i]==1)
res++;
}
return res;
}
tarjan最小割点算法模板
最新推荐文章于 2022-11-01 17:13:14 发布