图的连通性问题——无向图相关_求割顶
2011-08-09 06:10
232 查看
求割顶
割顶是去掉后让无向图不再连通的点。
求割顶的算法在DFS遍历的算法上形成。
什么样的点是割顶?
在一棵DFS树中,
1.根root是割顶 ------------- 它至少有两个儿子
2.其他点v是割顶
------------- 它有一个儿子u, 从u或者u的后代出发没有指向v祖先(不含v)的B边, 则删除v以后u和v的父亲不连通, 故为割顶。
割顶判定算法:
引入lowlink数组为 从当前点以及它的后代所能到达的点的开始访问时间的最小值。
Lowlink [u]= Min { pre[u]
Pre[v] (u,v)是后向边
Lowlink [v] (u,v)是树边,u在dfs树中是v的父亲 }
–对于DFS树根, 判断度数是否大于1
–对于其他点u, 如果不是根的直接儿子, 且Lowlink[u] >= d[P[u]], 则它的父亲v=P[u]是割点。
其实这个解释并不是特别明晰。。。
粗略的解释一下。。
求法就是枚举每个点,切断,dfs,若不能到达目标节点,
则当前被切断的点是割顶。(注意标记的点,dfs后要还原)
有一个小小的优化:
先从始点dfs一下。则割顶一定在这条路径上,
记录一下访问过的节点,能够减少枚举的点数。
引申的问题:如果有不能连通的情况,也可以从这次dfs中判断出来。
举个例子:有道题是裸求割顶的,看代码。(表示代码写的不好看。。)
code:
View Code
割顶是去掉后让无向图不再连通的点。
求割顶的算法在DFS遍历的算法上形成。
什么样的点是割顶?
在一棵DFS树中,
1.根root是割顶 ------------- 它至少有两个儿子
2.其他点v是割顶
------------- 它有一个儿子u, 从u或者u的后代出发没有指向v祖先(不含v)的B边, 则删除v以后u和v的父亲不连通, 故为割顶。
割顶判定算法:
引入lowlink数组为 从当前点以及它的后代所能到达的点的开始访问时间的最小值。
Lowlink [u]= Min { pre[u]
Pre[v] (u,v)是后向边
Lowlink [v] (u,v)是树边,u在dfs树中是v的父亲 }
–对于DFS树根, 判断度数是否大于1
–对于其他点u, 如果不是根的直接儿子, 且Lowlink[u] >= d[P[u]], 则它的父亲v=P[u]是割点。
其实这个解释并不是特别明晰。。。
粗略的解释一下。。
求法就是枚举每个点,切断,dfs,若不能到达目标节点,
则当前被切断的点是割顶。(注意标记的点,dfs后要还原)
有一个小小的优化:
先从始点dfs一下。则割顶一定在这条路径上,
记录一下访问过的节点,能够减少枚举的点数。
引申的问题:如果有不能连通的情况,也可以从这次dfs中判断出来。
举个例子:有道题是裸求割顶的,看代码。(表示代码写的不好看。。)
code:
View Code
var i,x,y,j,n,m,k,l,e,js,bb:longint; a:array[1..2000,1..2000]of longint; b,v,vv,jj:array[1..2000]of integer; procedure find(x:longint); var i,j:longint; begin v[x]:=1; if x=n then begin bb:=1;exit;end; for i:=1 to jj[x] do begin if (v[a[x,i]]=0) then find(a[x,i]); if bb=1 then begin inc(js); b[js]:=a[x,i]; if a[x,i]=n then b[js]:=0; break; end; end; end; procedure doing(x:longint); var i,j:longint; begin v[x]:=1; for i:=1 to jj[x] do if (v[a[x,i]]=0) then doing(a[x,i]); end; begin assign(input,'running.in'); reset(input); assign(output,'running.out'); rewrite(output); readln(n,e); for i:=1 to e do begin readln(x,y); inc(jj[x]);a[x,jj[x]]:=y; inc(jj[y]);a[y,jj[y]]:=x; end; find(1); for i:=1 to js do if b[i]<>0 then begin fillchar(v,sizeof(v),0); v[b[i]]:=1; doing(1); if v =0 then vv[b[i]]:=1; end; m:=0; for i:=1 to n do if vv[i]=1 then inc(m); writeln(m); for i:=1 to n do if vv[i]=1 then write(i,' '); close(input); close(output); end.
相关文章推荐
- [回忆向]关于有向和无向图连通性问题的yy证法
- poj 1523 SPF(无向图点的连通性问题)
- Androidpn相关问题
- 彻底弄懂Qt的编码(汉字乱码问题及相关函数作用)
- asp.net中动态修改action使server的Form传递表单值,及相关问题
- cxf 相关问题
- 关于本博客的版权相关问题
- lzg_ad:XPE下中文字体相关问题
- Linux下和编译器、程序的运行、环境变量等相关的常见问题
- 前端工作面试HTML相关问题
- 手机内存卡的相关路径问题
- android 自定义动态加载数据的折线图及相关问题解析
- 1006. 连通性问题
- 【Day24】几道值得研究注意的php相关问题(二)
- Android自定义View研究(六)--View中的原点坐标相关问题
- mysql中自增auto_increment功能的相关设置及问题
- cocos2d-x 多图层点击事件及管理相关问题记录
- C语言求解最长公共子字符串问题及相关的算法分析
- Python 频繁读取Mysql相关问题
- ajax相关问题