POJ - 3352 无向图的割和桥以及双连通分量

原创 2011年10月17日 13:48:31

    双连通分量是指图中每两个点都有两条完全不同的路径可到达..也就是去掉这个图的任意一个边一个点...两两之间依然可达..  

    图论中的桥...在有向图中是两个连通分量之间唯一的边(如果有多条那么都不是桥)...在无向图中是两个双连通分量之间的唯一边...

    而割指的是割点..割点肯定是和桥的端点...但桥的端点不一是割点..如:


   (1,4),(2,4),(3,4),(4,5),(4,6),(4,7)都是桥..所有点都是桥的端点...但是只有4是割点...1,2,3,5,6,7都不是割点..

   去掉一个连通图中的一个桥或者割点..这个连通图就将成为不连通的多个连通图..

   求无向图中的桥的方法是有Tarjan发明的..Byvoid大大的讲解很给力: http://www.byvoid.com/blog/biconnect/

   无向图的Tarjan和有向图求强连通分量的Tarjan很像...注意几个不同...

    1、求双联通分量时..同样要用到栈..但栈中不是放点..而是放边....

      2、DFS时不能从 a 递归到了 b..b又马上从a来更新...所以要多加一个notpre..代表递归b时是从哪个点进去的...防止这种情况..

      3、Low相等的点在无向图中就是在一个双连通图中...这个比有向图的方便..有向图还需要用栈来维护..通过判断退栈来判断强连通分量..

   如果要求桥和割点的话..做完Tarjan..扫描所有的边,有 DFN ( 终点 ) < LOW ( 起点 ) 的边就是桥...这条边的"终点"就是割点..

   回到POJ3352...题目给出了连通的无向图..并且两点直接最多只有一条边...求的是加几条边能使得该无向图整个变成一个双连通图..

   那么先对图做无向图的Tarjan...得到每个点所在的双连通记录在Low里....可以想象一下..如果把所有的双连通分量分别缩成一个点...那么整个图就是一棵树了..如果给一棵树..要史其成为一个双连通图...那么需要加( 叶子结点数+1)/2调边...

   这道题就是在做完Tarjan找作为叶子节点的双连通分量的个数k..然后答案就是(k+1)/2...

Program:

// POJ3352 加边做双连通图
#include<iostream>
#include<stack>
#include<math.h>
#define MAXN 5001
using namespace std;
struct pp
{  
    int x,y,next;   
}line[MAXN*5];
int n,m,link[MAXN],i,p,low[MAXN],dfn[MAXN],tp[MAXN],numtp,sum[MAXN];
bool instack[MAXN],used[MAXN];
stack<int> mystack;
void trajin(int h)
{
   int k;
   instack[h]=true;
   mystack.push(h);
   low[h]=dfn[h]=++p;
   k=link[h];
   while (k)
   {
      if (!dfn[line[k].y])
      {
            trajin(line[k].y);
            low[h]=min(low[h],low[line[k].y]);     
      }else
      if (instack[line[k].y])
      {
            low[h]=min(low[h],dfn[line[k].y]);           
      }
      k=line[k].next;   
   }
   k=h;
   if (low[k]==dfn[k])
   {
        numtp++;              
        do 
        {
             k=mystack.top();
             tp[k]=numtp;
             mystack.pop();
             instack[k]=false;         
        }while ( low[k]!=dfn[k]);              
   }
   return; 
} 
void getanswer()
{
    int i;
    memset(instack,false,sizeof(instack));
    while (!mystack.empty()) mystack.pop();
    memset(tp,0,sizeof(tp));
    memset(dfn,0,sizeof(dfn));
    p=0; numtp=0;
    for (i=1;i<=n;i++) 
     if (!dfn[i]) 
       trajin(i); 
    for (i=1;i<=n;i++)
     if (!tp[i])
     {
         printf("\n");
         return;           
     }   
    memset(link,0,sizeof(link));
    memset(sum,0,sizeof(sum)); 
    for (i=1;i<=m;i++)
    if (tp[line[i].x]!=tp[line[i].y])
    {
        p++;
        sum[tp[line[i].x]]++;
    }   
    for (i=1;i<=n;i++)
     if (!sum[tp[i]]) 
       printf("%d ",i);  
    printf("\n");
    return;
}
int main()
{ 
    while (~scanf("%d%",&n))
    {
          if (!n) break;
          scanf("%d",&m);
          memset(link,0,sizeof(link));
          memset(line,0,sizeof(line));
          for (i=1;i<=m;i++)
          {
              scanf("%d%d",&line[i].x,&line[i].y);
              line[i].next=link[line[i].x];
              link[line[i].x]=i;
          }
          getanswer();
    }
    return 0;   
}






版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

无向连通图的割点、桥

无向连通图的割点、桥 泳裤王子原创,转载请注明出处 http://blog.csdn.net/tclh123/article/details/6705392 预备知识:        割点集合 ...
  • tclh123
  • tclh123
  • 2011年08月21日 00:40
  • 6879

无向图的割顶和桥

定义: 1.对于无向图,如果删除某个点u后,连通分量的数目增加,称u为图的关节点或割点。对于连通图来说,删除割点后,图将变得不再连通。 2.设 low(u)low(u) 为u及其后代所能连回...

无向图的割顶和桥,无向图的双连通分量入门详解及模板

割顶和桥:对于无向图G,如果删除某个节点u后,连通分量数目增加,则称u为图的割顶;如果删除某条边后,连通分量数目增加,则称该边为图的桥。对于连通图删除割顶或桥后都会使得图不再连通以下我,我们利用dfs...

poj3177-tarjan求桥/割边

题目大意:有F个牧场,1 给定现有的R条直接连接两个牧场的路,F-1 若low[v]>dfn[u],则(u,v)为割边。但是实际处理时我们并不这样判断,因为有的图上可能有重边,这样不好处理...

poj1236-Tarjan算法

poj1236--Tarjan算法 题目大意:     一些学校连成了网络, 在学校之间存在某个协议:每个学校都维护一张传送表,表明他们要负责将收到的软件传送到表中的所有学校。如果A在B的表中,那...

hdu5251最小矩形覆盖

题意(中问题直接粘吧) 矩形面积 Problem Description 小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些矩形包围起来的面积最小的矩形的面积是多少。 ...

【HNOI2007】bzoj1185 最小矩形覆盖

旋转卡壳
  • sdfzyhx
  • sdfzyhx
  • 2017年04月14日 09:09
  • 165

POJ-3352-无向图的割顶和桥-求边-双连通分量

Road Construction Description It's almost summer time, and that means that it's almost summe...

poj 3352 求双连通分量 (无向图)

转:http://blog.csdn.net/lin375691011/article/details/18774187题目大意: 给定图G,求最少加多少边可以成为双连通图。解题思路: 1、求图G...

poj 3177 & 3352 【无向图双连通分量Tarjan】

题目:poj 3177 & 3352 题意:大概意思就是给你一个无向图,让你添加最少的边,让所有点都双连通。 分析:双连通的定义就是任意两个点至少有两条路可达。 其实做法跟添加最...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ - 3352 无向图的割和桥以及双连通分量
举报原因:
原因补充:

(最多只允许输入30个字)