圖之鄰接矩陣,深度遍歷,廣度遍歷,連通分量個數
阿新 • • 發佈:2018-12-19
1.深度遍歷 DFS
類似於樹的先根遍歷
如圖,上述圖的深度遍歷輸出為ADCBE
給出一個圖的鄰接矩陣,對圖進行深度優先搜尋,從頂點0開始
class Graph { private: int flag[N];//狀態陣列 int Vexnum;//圖的頂點數量 int Matrix[N][N]; //鄰接矩陣 void DFS(int v); public: Graph() { for(int i=0;i<N;i++) flag[i]=0; } void DFStra(); void SetMatrix(int n,int p[N][N]); } void Graph::SetMatrix(int n,int p[N][N])//設定鄰接矩陣 { Vexnum=n; for(int i=0;i<Vexnum;i++) for(int j=0;j<Vexnum;j++) { Matrix[i][j]=p[i][j]; } } void Graph::DFStra() { int i; for(i=0;i<Vexnum;i++)//可能有多個連通圖 { if(flag[i]==0)//找到一個狀態為0的頂點 DFS(i); } cout<<endl; } void Graph::DFS(int v) { int w,i,k; flag[v]=1;//把這個頂點的狀態設定為1 cout<<v<<" "; int temp[N]; for(i=0;i<Vexnum;i++) temp[i]=0; k=0; for(i=0;i<Vexnum;i++)找到與當前這個頂點有連線的頂點,並存入temp陣列中 { if(Matrix[v][i]==1) temp[k++]=i; } i=0; for(i=0;i<k;i++)//對這個幾個頂點遞迴遍歷 { w=temp[i]; if(flag[w]==0) DFS(w); } } int main() { int t,i,num,j; int x[N][N]; int n; cin>>t; while(t--) { cin>>n; for(i=0;i<n;i++) for(j=0;j<n;j++) cin>>x[i][j]; Graph p; p.SetMatrix(n,x); p.DFStra(); } }
測試的資料為:
樣例輸入
2
4
0 0 1 1
0 0 1 1
1 1 0 1
1 1 1 0
5
0 0 0 1 1
0 0 1 0 0
0 1 0 1 1
1 0 1 0 0
1 0 1 0 0
樣例輸出
0 2 1 3
0 3 2 1 4
2.廣度遍歷BFS 及 計算連通分量個數
廣度遍歷類似於樹的層次遍歷
例如:一個連線矩陣如下
0 1 1 0 0 0 0 0
1 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 1 1 0
0 0 0 0 1 0 0 0
0 0 0 0 1 0 0 0
0 0 0 1 0 0 0 0
該矩陣的圖示如下
可知連通分量為3,通過廣度遍歷輸出的結果為ABCDIEFH
#include<bits/stdc++.h> using namespace std ; #define N 20 class Graph { private: int flag[N]; int num;//連通分量個數 int Vexnum; string temp[N]; int Matrix[N][N]; //邊陣列 void BFS(int v); public: void BFStra() ; Graph(string x[],int n) { int i; num=0; Vexnum=n; for(i=0;i<Vexnum;i++) temp[i]=x[i]; for(int i=0;i<N;i++) flag[i]=0; for(int i=0;i<Vexnum;i++) for(int j=0;j<Vexnum;j++) { Matrix[i][j]=0; } } int find(string x); void SetMatrix(); void display(); void GetNum(); }; void Graph::SetMatrix()//對鄰接矩陣初始化 { int i,k,j,x,y,h; string a,b; cin>>k; i=0; while(k--) { cin>>a>>b; x=find(a); y=find(b); Matrix[x][y]=1; Matrix[y][x]=1; } } void Graph::BFStra() { int i=0; for(i=0;i<Vexnum;i++) if(flag[i]==0) { BFS(i); } } void Graph::BFS(int v) { int w,u; int i,k; int temp[N]; queue<int> p; k=0; for(i=0;i<Vexnum;i++) flag[i]=0; for(v=0;v<Vexnum;v++) { if(flag[v]==0) { num++; flag[v]=1; cout<<v<<" "; p.push(v); //把找到滿足要求的頂點放入佇列中 while(!p.empty()) { k=0; u=p.front(); if(flag[u]==0) { cout<<u<<" "; flag[u]=1; } p.pop(); for(i=0;i<Vexnum;i++)//查詢與當前頂點連線的頂點 { if(Matrix[u][i]==1&&flag[i]==0) { p.push(i); } } } } } cout<<endl; } int Graph::find(string x) { for(int i=0;i<Vexnum;i++) if(x==temp[i]) return i; } void Graph::display() { int i,j; for(i=0;i<Vexnum;i++) { if(i!=0) cout<<" "; cout<<temp[i]; } cout<<endl; for(i=0;i<Vexnum;i++) { for(j=0;j<Vexnum;j++) { if(j!=0) cout<<" "; cout<<Matrix[i][j]; } cout<<endl; } cout<<num<<endl; } int main() { int t,i,j; string x[N]; int n; cin>>t; while(t--) { cin>>n; for(i=0;i<n;i++) cin>>x[i]; Graph p(x,n); p.SetMatrix(); cout<<"廣度遍歷結果:" <<endl; p.BFStra(); cout<<endl; p.display(); cout<<endl; } }