1. 程式人生 > >關鍵城市--圖的割點 《啊哈算法》代碼詳解

關鍵城市--圖的割點 《啊哈算法》代碼詳解

ID highlight int 如果 div dfs 結點 () min

#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;
}

  

關鍵城市--圖的割點 《啊哈算法》代碼詳解