1. 程式人生 > >C++程式碼,資料結構-連通圖的關節點

C++程式碼,資料結構-連通圖的關節點

連通圖的關節點,按照書上使用鄰接表的作為圖的儲存,

#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中,,,,