void dfs(int u,int fa)
{
int i,cnt=0;
bool tag=true;
flag[u]=1;
dfsnum[u]=low[u]=++Time;
for(i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(v==fa||dfsnum[v]>=dfsnum[u])
{
tag=false;
continue;
}
stack[top++]=i;
if(!flag[v])
{
dfs(v,u);
cnt++;
low[u]=min(low[u],low[v]);
if((u==root&&cnt>1)||(u!=root&&low[v]>=dfsnum[u]))//割点
{
int dnum=0,bnum=0,e,s,t;//接来下操作求双连通分支
do{
e=stack[--top];
s=edge[e].u;
t=edge[e].v;
bnum++;
if(!vis[s])
{
dnum++;
vis[s]=1;
}
if(!vis[t])
{
dnum++;
vis[t]=1;
}
}while(!(s==u&&t==v));
if(dnum<bnum)
ans2+=bnum;
}
if(low[v]>dfsnum[u])//桥
ans1++;
}
else if(flag[v]==1)
low[u]=min(low[u],dfsnum[v]);
}
flag[u]=2;
}
找割点,桥以及求双连通分支的模板
最新推荐文章于 2023-05-08 12:31:16 发布