暑期集训——求割点割边

 

求割边割点

对于一个连通图,删去某个点(删去一个点即把该点和与该点相邻接的边都删去)的集合得到的图将不再连通,删去该集合的任意子集该图依然连通,则称其为该图的一个点割集,若该集合只有一个点组成,则称其为割点。

同样对于一个连通图删去某个边的集合(删去一条边仅删去该条边即可)得到的图将不再连通,删去该边集合的任意子集该图依然连通,则称其为该图的边割集,若该集合只有一条边组成,则称其为割边即桥。

求割边割点最直接的方法就是按照定义,删去点或边然后对图进行遍历,看是否仍连通,但要求一个图的割点割边对整个图的每个点和每条边都需要做一下试探,时间复杂度太高。

求割边割点的过程,以某一个点开始做dfs,采用数组low[i],dep[i]表示一个节点可以到达的除其父亲外的最早被访问的点,dep表示该点的深度。

若有节点u有子节点v,且low[v]>=dep[u]则点u是割点。

若有low[v]>dep[u]则边(u,v)为割边.

 1int low[MAX],dep[MAX],mark[MAX],cutpoint[MAX];
 2void dfs(int s,int father,int depth)
 3{
 4   int u,v,tot=0;
 5   mark[s]=1;
 6   low[s]=dep[s]=depth;
 7   for(int i=0;i<mp[s].size();i++)
 8   {
 9      v=mp[s][i];
10      if(mark[v]==1&&v!=father&&dep[v]<low[s])
11      low[s]=dep[v];
12      else if(mark[v]==0
13      {
14         tot++;
15         dfs(v,s,depth+1)
16         if(low[v]<low[s])
17         low[s]=low[v];
18         if((s==root&&tot>1)||(s!=root&&low[v]>=dep[s]))
19         cutpoint[s]=1;
20         if(low[v]>dep[s])
21         //标记边(s,v)为割边 
22      }

23   }

24   mark[s]=2;
25}

26
27

posted on 2010-07-12 19:44 YUANZX 阅读(1287) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2010年7月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

导航

统计

常用链接

留言簿

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜