zoukankan      html  css  js  c++  java
  • Tarjan的求双连通分量算法

    哎~气死我了!昨天晚上都写好了……一不小心把网页关了,写的全没了……MD

    什么是双连通分量DCC(Double connected component)?

    首先说一下一个无向连通图,若去掉任一点或任一边都不影响该图的连通性(本来是连通的,现在仍连通),那么该图是一个双连通图(该图的DCC只有一个即本身)。

    DCC是一个无向连通图(注意是无向连通图不是有向图,别把强连通分量与他们搞混了!)的子图,该子图是一个双连通图(尽可能大的双连通图,也就是尽可能包含更多的点)。也就是说一个无向连通图的DCC需要满足三个条件:1.它是该无向连通图的子图 2.该子图是一个双连通图 3.使该子图尽可能的大

    什么是割点、桥?

    一个无向连通图,去掉一点或一边后影响了改图的连通性(本来是连通的,现在不连通了),则该点就是割点或该边就是桥。

    求DCC的算法的分析,我就不说了……就是说了也难以理解,直接贴上加注释的code,你自己画个图,跟着程序走一遍,慢慢体会体会!

    //----------DCC------------------

    int dfn[MAXNODE],low[MAXNODE],index;//dfn记录各点被访问次序,low是追溯到DCC的根节点
    //的dfn的值,当根节点的某个直接儿子节点的low值大于或等于根节点的dfn的值时,就可以从
    //栈中取值了,直到取到根节点为止时一个DCC

    int stack[MAXNODE],top;//栈:用深搜搜索节点并依次存储各个节点—以便于找到DCC(即当
    //发现环时就是一个DCC,用low标记的,从该栈中取值取到该根节点为止)

    int id_dcc[MAXNODE],cnt_dcc;//id_dcc:名副其实即DCC的id(编号),存储各节点的所在的
    //编号(就是你给他们编的号,从1-n)cnt_dcc就是编号下标!

    int father[MAXNODE];//由于求DCC是在一个无向连通图中,即为双向的图,该father就是为了
    //防止某一节点又访问上一个节点(上一个节点搜出该节点)

    void DFS_DCC(int cur)
    {
    int next; //next为cur节点下的节点
    dfn[cur]=low[cur]=++index;
    stack[
    ++top]=cur;
    for(Node *p=G[cur];p;p=p->next)
    {
    next
    =p->num;
    if(!dfn[next])
    {
    father[next]
    =cur; //额,可以不用。。
    DFS_DCC(next);
    if(low[next]<low[cur]) //更新low使每一个DCC中的low的值==根节点low值
    low[cur]=low[next];
    if(low[next]>=dfn[cur])//当发现节点cur的儿子节点next的low值>=dfn[cur]
    { //则就要取栈,即是时候取出DCC了。为什么?因为不
    cnt_dcc++; //这样就不对了^_^!(具体原因,自己举几个例子try)
    do
    {
    next
    =stack[top--];
    id_dcc[next]
    =cnt_dcc;
    }
    while(next!=cur);
    top
    ++; //这里为什么要++因为连着DCC是有共同节点的(举例try)
    //不++肯定要出错!也许我这code跟别人不一样,其实
    //思想都一样,只是具体实现的code有小小的差异罢了
    }
    }
    else if(next!=father[cur] && dfn[next]<low[cur])
    {
    //呃呃呃!其实不用这个father数组都可以了,只需
    //dfn[next]<low[cur]就行了
    low[cur]=dfn[next];
    }
    }
    }
    void solve()
    {
    index
    =top=cnt_dcc=0;
    memset(dfn,
    0,sizeof(dfn));//初始化各下标及dfn
    DFS_DCC(1);//由于是无向连通图,只需深搜一个节点就都可以都到了
    }

    上面的是求DCC,有时候要求割点,求桥,你根据定义自己想想……都差不来啊!

    可能解释的不够清楚,有什么问题?可以问我饿!或者发现有什么不对或不好的地方,欢迎指正!

    不过我也只是知道这样实现,并不真正懂得为什么。你如果问我为什么是这样,它的原理是什么?我会给你说:因为只有这样才能实现,它原理就在实现中^_^!如果大虾你理解的深的话……希望能给小弟分享一下!

  • 相关阅读:
    apache安全—用户访问控制
    hdu 3232 Crossing Rivers 过河(数学期望)
    HDU 5418 Victor and World (可重复走的TSP问题,状压dp)
    UVA 11020 Efficient Solutions (BST,Splay树)
    UVA 11922 Permutation Transformer (Splay树)
    HYSBZ 1208 宠物收养所 (Splay树)
    HYSBZ 1503 郁闷的出纳员 (Splay树)
    HDU 5416 CRB and Tree (技巧)
    HDU 5414 CRB and String (字符串,模拟)
    HDU 5410 CRB and His Birthday (01背包,完全背包,混合)
  • 原文地址:https://www.cnblogs.com/fornever/p/2179448.html
Copyright © 2011-2022 走看看