关键城市--图的割点 《啊哈算法》代码详解

Posted zgqblogs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关键城市--图的割点 《啊哈算法》代码详解相关的知识,希望对你有一定的参考价值。

#include<iostream>
using namespace std;
int n,m,e[9][9],root;
int num[9],low[9],flag[9],index;

void dfs(int cur,int father)
{
    int child=0;
    index++;
    num[cur]=index;
    low[cur]=index;
    for(int i=1;i<=n;i++){
        if(e[cur][i]==1){//i是不通过父亲可以到达的节点
            if(num[i]==0){//如果是爸爸,就不会是0
                          //如果不是爸爸,就一定是自己祖先
                          //也就是说,你走了一个环
                          //因为这是深搜,当然这个祖先并不一定是最高层的那个,而是,总之要比爸爸先访问到
                child++;
                dfs(i,cur);//通过自己的儿子开始找祖先了
                low[cur]=min(low[cur],low[i]);//既然cur可以不通过爸爸到达i,那么,i可以不通过自己爸爸到达的节点,cur一样可以到
                                              //这样的话,虽然cur比i先访问到,但是极有可能通过i找到已经访问过个点了。
                                              //如果真能找到,cur就不是割点了。
                if(cur!=root&&low[i]>=num[cur]){//这就是找不到了,因为low的初始值一定比num大,所以不通过爸爸找不到祖宗的话,
                                                //low[i]的值是不会比num[cur]小的。
                    flag[cur]=1;

                }
                if(cur==root&&child==2){//child等于2的时候,说明根节点一定是割点
                                        //因为,只有当自己的儿子没有被访问过,才会是自己的亲儿子
                                        //简单来说,在程序开始,确定好了一个与之相邻的结点是儿子了之后,就会马上开始深搜
                                        //搜索之后,与之相邻的其他结点,如果被访问过了,则不会进入这个if,所以就不会有新的儿子
                                        //所以儿子数唯二,根节点一定是割点。
                                        //儿子数为三也是的,但是再成为三之前,已经在成为二的时候被确认过了,所以写等于2没有问题。
                    flag[cur]=1;
                }
            }
            else if(i!=father){//绝不是爸爸,而是祖先
                low[cur]=min(low[cur],num[i]);//这句话才是核心啊!!!
            }
        }
    }
    return;
}



int main()
{
    int x,y;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            e[i][j]=0;
        }
    }

    for(int i=1;i<=m;i++){
        cin>>x>>y;
        e[x][y]=1;
        e[y][x]=1;

    }

    root=1;
    dfs(1,root);

    for(int i=1;i<n;i++){
        if(flag[i]==1){
            cout<<i<<" ";
        }
    }
    //cout<<low[6]<<endl;
}

  

以上是关于关键城市--图的割点 《啊哈算法》代码详解的主要内容,如果未能解决你的问题,请参考以下文章

[啊哈算法]关键道路(图的割边)

《啊哈算法》——割点割边二分图

图的割点算法图的割边算法

『Tarjan算法 无向图的割点与割边』

Tarjan算法:求解图的割点与桥(割边)

图的割点与割边