如何判斷圖的連通


判斷圖是否連通,可用dfs和bfs遍歷圖算法,注意點數目較多,又是稀疏圖的話,最后使用鄰接表的方法存儲。另外推薦采用的是並查集的方法。初始化時將每個節點看作一個集合,則每給出一條邊即把兩個集合合並。最后遍歷所有點,有幾個集合便有幾個連通分量,若只有一個集合說明圖連通。並查集方法通常情況下時間效率較高,還能判斷一個圖是否有回路,在kruskal算法中也可以使用。

(1)DFS判斷

int count = 0;
void DFS(MGrap G. int i)
{
    int j = 0;
    visited[i] = 1;
    count++;
    for(j=0; j<G.numVertexes; j++)
    {
        if(G.arc[i][j]==1 && !visited[j])//i和j有關系相鄰,並且j頂點沒有被訪問過
        {
            DFS(G, j);
        }
    }
}

從某一點出發開始DFS,到最后,只需要判斷最后count的值是否是全部的節點就可以,如果小於總節點數,則證明是不連通的,如果相等,則證明是連通的。

還可以訪問完一個節點,就將其刪除掉,可提高遍歷速度

void dfs(int s){             //遞歸深搜
    vis[s]=true;
    for(int i=0;i<g[s].size();++i){
        if(vis[g[s][i]]) g[s].erase(g[s].begin()+i);//刪除圖中已經遍歷過的點,可提高遍歷速度
        else dfs(g[s][i]);
    }
}

bool judge(){                //判斷是否所有點已被遍歷過
    for(int i=1;i<=n;++i)
        if(!vis[i])
            return false;
    return true;
}

(2)BFS判斷

void bfs(int s){            //用隊列廣搜
    queue<int> q;
    q.push(s);
    while(!q.empty()){
        int x=q.front();
        q.pop();
        vis[x]=true;
        for(int i=0;i<g[x].size();++i){
            if(vis[g[x][i]]) g[x].erase(g[x].begin()+i);//刪除圖中已經遍歷過的點,可提高遍歷速度
            else q.push(g[x][i]);
        }
    }
}

bool judge(){                   //判斷是否所有點已被遍歷過
    for(int i=1;i<=n;++i)
        if(!vis[i])
            return false;
    return true;
}

同樣如果從某一個節點廣度搜完,有未訪問到的節點,那么該圖一定是不連通的。

(3)並查集

並查集一般用來判斷圖的連通性,還可以判斷圖中是否有回路。

如果並查集最后只有一個連通分量,證明此圖連通,否則此圖不連通

int set[1000005];

int find(int x){

   return x==set[x]?x:(set[x]=find(set[x]));   //遞歸查找集合的代表元素,含路徑壓縮。

}
int main()

{

   int n,m,i,x,y;

   scanf("%d%d",&n,&m);

   for(i=1;i<1000005;++i)        //初始化個集合,數組值等於小標的點為根節點。

       set[i]=i;

   for(i=0;i<m;++i){

       int a,b;

       scanf("%d%d",&a,&b);

       int fx=find(a),fy=find(b);

       set[fx]=fy;                      //合並有邊相連的各個連通分量

   }

   int cnt=0;

   for(i=1;i<=n;++i)          //統計集合個數,即為連通分量個數,為一時,圖聯通。

       if(set[i]==i)

           ++cnt;

   if(cnt==1)

       printf("yes\n");

   else printf("no\n");

   return 0;

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM