Chinaunix首页 | 论坛 | 博客
  • 博客访问: 360810
  • 博文数量: 19
  • 博客积分: 1450
  • 博客等级: 上尉
  • 技术积分: 262
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-17 23:23
个人简介

右手代碼,左手《史記》

文章分类
文章存档

2019年(1)

2014年(5)

2013年(2)

2011年(1)

2010年(6)

2009年(4)

我的朋友

分类: C/C++

2010-09-24 17:57:06

源码:

文件:AdjList.rar
大小:263KB
下载:下载

搞了一下午,终于把割点算法弄明白了,总结一下吧!正在学习C++,所以用C++的类思想实现了一下,确实变的很模块化!
求割点有两种方法:1.笨方法,遍历每个点,将每个点都从图中挖出去,之后对图进行遍历,如果遍历不完整就证明挖出去的这个点为割点。
2.按照定理的方法,定理的内容是这样的:Let v be a nonroot vertex of Gπ. Prove that v is an articulation point of G if and only if v has a child s such that there is no back edge from s or any descendant of s to a proper ancestor of v。大概意思就是:对每个点维持用两个数组,P,Q,P记录的是此点通过回退边能够访问的最小点,Q记录的是此点在遍历过程中被访问的次序。通过比较Q[v]和P[v's child],如果P[v's child]>=Q[v]则,v为一个割点,否则v不是割点。
除此之外,还有其他需要注意的(主要针对方法2):求关键点(即割点,下同)算法中,对于关键点的判断有两种可能:1,根节点有两棵或以上的子树,那么根就是关键点。 2,指向父结点的边不算回边
       以上标红字的两点非常关键,写成代码形式为:

while(p){
        if(!visited[p->adjvex]){
            if(i == ROOT){
                if(++rootson > 1)
                    ArtPoint[i] = true;
            }
            Tarjan_cut_bridge(visited, p->adjvex, i);
            low[i] = Min(low[i], low[p->adjvex]);
            if(i!=ROOT&&low[p->adjvex]>=dfn[i])
                ArtPoint[i] = true;
            if(low[p->adjvex]>dfn[i])
                Bridge[i] = p->adjvex;
        }else if(p->adjvex!=father){
            low[i] = Min(low[i], dfn[p->adjvex]);
        }
        p = p->next;
    }


       一下是伪代码:



Start:
设S为起始顶点
for 每个顶点 v ∈V
      标记 v 未访问
end for
predfn = 0 ;count = 0 ;rootdegree = 0
dfs(s);

过程 dfs(v )
//注意这个过程中,把v看成根 ,w是子节点,不要与上面的文字分析混了 .(这里的w与上面的s同)

标记v已访问;artpoint = false ;predfn = predfn +1 ;
Q[v] =predfn ; P[v] = predfn ;
for(每条边 (v,w )∈E) {
         if (v,w)为树边 {
                dfs(w)
                if(v == s )then {
                 rootdegree ++ ;
                 if(rootdegree == 2 ) then artpoint = true ;
                }
                else {
                        P[v] = min{ P[v] , P[w]} ; // 给P[V]赋值,以便为上层提供信息.

                      // 针对V的判断,只需要知道P[w] 和Q[v]即可,对P[v] 的赋值是为上层提供信息

              if(P[w] >= Q[v])
                                artpoint = true ; // Q[w]
                    }
       }
       else if(v,w) is back edge {
      P[v] = min{ P[v], Q[w] } // P[W]没有被有效赋值

       }
else {/*do nothing*/}
end for

if(artpoint ){
    count ++ ;
    A[count] = v;
}

          
}


参考文章:http://www.cnblogs.com/feature/articles/1802640.html(C实现的源码)

阅读(5567) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-09-26 15:24:36

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com