Tarjan思想求割点

一、算法描述

  Tarjan算法求割点仍然用了tarjan思想中dfs求prenum的dfs序号,parent的dfs树,以及lowest这样一个记录最早回溯位置的数组。lowest计算时求下列情况的最小值,即:

lowest[u]的值为:prenum[u];如果存在一条非树边(u,v),使得u与一个树上顶点连通,这种情况下的prenum[v];u的所有子节点的lowest

  tarjan处理完成后根据下列标准计算割点:

1. 如果DFS树根节点的子节点≥2,那么根节点是一个割点(充要条件)

2. 对于各顶点u,令p=parent[u],如果prenum[p]≤lowest[u],那么p是一个割点(此处注意,p是割点而不是u是割点,如果p是根节点那么按1计算)

二、代码

tarjan预处理:

 1 int order=0;
 2 int dfs_tarjan(int now,int last){
 3     prenum[now]=++order;
 4     parent[now]=last;
 5     lowest[now]=min(lowest[now],prenum[now]);
 6     vis[now]=true;
 7     for(int i=0;i<a[now].size();i++){
 8         int to=a[now][i];
 9         if(del[to])
10             continue;
11         if(vis[to]){
12             if(parent[now]!=to)
13                 lowest[now]=min(lowest[now],prenum[to]);
14         }
15         else lowest[now]=min(lowest[now],dfs_tarjan(to,now));
16     }
17     return lowest[now];
18 }

统计割点数量:

 1 order=0;
 2 for(int j=1;j<=n;j++){
 3     vis[j]=false;
 4     lowest[j]=INT_MAX;
 5 }
 6 int now=1;
 7 while(del[now])
 8     now+=1;
 9 dfs_tarjan(now,now);
10 int cnt=0;
11 for(int j=1;j<=n;j++){
12     if(del[j])
13         continue;
14     if(parent[j]==now&&j!=now)
15         cnt+=1;
16 }
17 if(cnt>=2)
18     res+=1;
19 for(int j=1;j<=n;j++){
20     if(del[j])
21        continue;
22     int p=parent[j];
23     if(p==now)
24         continue;
25     if(prenum[p]<=lowest[j])
26         res+=1;
27 }

 

转载于:https://www.cnblogs.com/shao0099876/p/9437520.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值