判断一个点是否是割点的两个条件:
1、如果一个点v是根结点并且它的子女个数大于等于2 则v是割点。因为有大于等于2个子树,删除根后,剩下的图才会分成至少两半 ;
2。如果点v不是根结点,并且存在她的一个子女u,使得low[u]>=dfn[v],则v是割点
void tarjan(int u,root)
{
int root_son=0;
dnf[u]=low[u]=++dep ;
vist[u]=1;
for(int i = head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(!dnf[v])
{
tarjan(v,u);
low[u] =min(low[u],low[v]) ;
if( u != root && dfn[u] <= low[v]) //u不是根
cut[u]=true; //u是割点,或者用一个记录割点数目来ans++ ;
root_son++ ;
}
else if(vist[v])
{
low[u] =min(dnf[v],low[u]);
}
}
if(u==root && root_son >= 2 ) //当u是根是,别忘了判断
cut[u]=true;
}
for(int i=1;i<=n;i++)
{
if( ! dnf[i] )
Tarjan(i,i);
}
for(int i=1;i<=n;i++)
if(cut[i])
ans++; //割点个数数