C++程式碼,資料結構-連通圖的關節點
阿新 • • 發佈:2019-02-16
連通圖的關節點,按照書上使用鄰接表的作為圖的儲存,
#include<iostream> #include<fstream> using namespace std; //圖的鄰接表的表示 #define max_ver 20 struct Arcnode{ int adjvex; //該弧所指向頂點的位置 Arcnode *nextarc; }; struct vnode{ char data; Arcnode *firstarc; }; typedef enum{dg,udg}Graphkind;//有向圖,無向圖 typedef vnode Adjlist[max_ver]; struct Mgraph{ Adjlist vertices; int vexnum,arcnum; Graphkind kind; }; void createUDG(Mgraph &M){ M.kind=udg; cout<<"請輸入無向圖的節點數和邊數"<<endl; cin>>M.vexnum>>M.arcnum; cout<<"請輸入無向圖的頂點"<<endl; for(int i=0;i!=M.vexnum;++i){cin>>(M.vertices)[i].data; M.vertices[i].firstarc=NULL;} cout<<"請一次輸入各頂點的度以及其各邊的資訊"<<endl; int x; cout<<"請輸入第一個頂點的度"<<endl; for(int i=0;i!=M.vexnum;++i){ cin>>x; for(int j=0;j!=x;++j){ Arcnode* tem=new Arcnode; cin>>tem->adjvex; tem->nextarc=M.vertices[i].firstarc; M.vertices[i].firstarc=tem; } if(i!=M.vexnum){ cout<<"請輸入下一個頂點的度"<<endl;} } } void printgraph(Mgraph M){ cout<<"這是鄰接表示圖的表現方式:"<<endl; cout<<"圖的頂點,頂點的度 ,與其鄰接的點的位置"<<endl; for(int i=0;i!=M.vexnum;++i){cout<<(M.vertices)[i].data<<" "; Arcnode *p; p=M.vertices[i].firstarc; for(;p!=NULL;p=p->nextarc){ cout<<p->adjvex<<" "; } cout<<endl; } cout<<endl; } int visited[1000]; //尋找連通圖的關節點 int low[1000]; int counts=1; //演算法7.11 low[v]的定義應該是v的後代以及一條回邊能到達的最高祖先的dfs void Dfsarticul(Mgraph G,int v0,int &counts){ int mins; visited[v0]=mins=++counts; //v0是第counts個訪問的節點 for(Arcnode *p=G.vertices[v0].firstarc; p;p=p->nextarc ){//對v0的每個鄰接頂點進行檢查 int w=p->adjvex; //w為鄰接點 if(visited[w]==0){ //如果未被訪問,繼續deep、 Dfsarticul(G,w,counts); //返回前求得low[w]; if(low[w]<mins)mins=low[w]; //其後代的low[]小於mins 則重置mins if(low[w]>=visited[v0]){cout<<G.vertices[v0].data<<" "; }//如果v0的某個孩子的low大於visited[v0],即沒有回指,則是關節點 } else if(visited[w]<mins){ mins=visited[w];} //如果被訪問。則w為v0的祖先, } low[v0]=mins; } //演算法7.10 void Findarticul(Mgraph G){ visited[0]=1;//0號節點為根 for(int i=1;i!=G.vexnum;++i){visited[i]=0;} //其他設定為0 ,未訪問 Arcnode *p=G.vertices[0].firstarc; int v; v=p->adjvex; Dfsarticul(G,v,counts);//從v節點開始deeptravel查詢關節點 if(counts<G.vexnum){//沒有遍歷完,說明有兩顆子樹 cout<<G.vertices[0].data<<" ";//根為關節點,繼續遍歷。 while(p->nextarc){ p=p->nextarc; v=p->adjvex; if(visited[v]==0){Dfsarticul(G,v,counts);} } } } int main() { ifstream infile("rebuf.txt"); cin.rdbuf(infile.rdbuf()); Mgraph M; createUDG(M); printgraph(M); cout<<"\n\n\n"; Findarticul(M); return 0; }
此原始檔利用了重定向的方法,不是每次都輸入
rebuf.txt:
13 17
a b c d e f g h i j k l m
4 1 2 5 11
6 0 2 3 6 7 12
2 0 1
2 1 4
1 3
1 0
4 1 7 8 10
3 1 6 10
1 6
2 11 12
2 6 7
3 0 9 12
3 1 9 11
圖如上圖所示,
程式輸出
g b d b a
b多輸出的了一次 。。。尋找bug中,,,,