圖論Graph Theory(1):圖的表示法及遍歷

一、圖的表示法

1.鄰接表

1.1採用STL中vector存圖
vector<int>G[N];
G[v].push_back(u);//v點與u點聯通
1
5
6
9
7
2
3
8
4

例如:

連接的點
G[1] 5 6
G[2] 7
G[3] 8
G[4]
G[5] 9
G[6] 5 9
G[7] 1
G[8] 4
G[9] 1
1.2採用鏈表的連接方式存圖

2.鄰接矩陣

2.1採用二維數組存取鄰接矩陣

map[i][j]={true若存在邊edge(i,j)false其他情況map[i][j]= \begin{cases} true& \text{若存在邊edge(i,j)}\\ false& \text{其他情況} \end{cases}

bool map[N][N];
map[i][j]=true;//i,j存在邊

二、圖的遍歷

2.1深度優先搜索(DepthFirestSearch)

時間複雜度:顯然鄰接表爲O(|V|+|E|),鄰接矩陣爲O(|V|^2)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
using namespace std;
const int N = 100005;

struct E{
	int u,v;
	//E(int a,int b){u=a,v=b;}
};

vector<int>G[N];
vector<E>edge;
bool vis[N];

void dfs(int num){
	vis[num]=true;
	for(int i=0;i<G[num].size();i++){
		if(!vis[G[num][i]]){
			struct E temp;
			temp.u=num;
			temp.v=G[num][i];
			edge.push_back(temp);
			dfs(G[num][i]);
		}
	}
}
void depthFirstSearch(const int n){
	for(int i=1;i<=n;i++){
		if(!vis[i]){
			dfs(i);
		}
	}
	for(int i=0;i<edge.size();i++){//輸出邊集
		cout<<edge[i].u<<" "<<edge[i].v<<endl;
	}
}
int main(){

	int n=0,m=0;	\\n個頂點,m條邊
	int u=0,v=0;
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>u>>v;
		G[u].push_back(v);
		G[v].push_back(u);
	}

	depthFirstSearch(n);

	return 0;
}

樣例輸入

9 9
1 5
1 6
1 7
2 7
3 8
4 8
5 6
5 9
6 9

樣例輸出

1 5
5 6
6 9
1 7
7 2
3 8
8 4

2.2廣度優先搜索(BreadFirestSearch)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <queue>
using namespace std;
const int N = 100005;

struct E{
	int u,v;
	//E(int a,int b){u=a,v=b;}
};
vector<int>G[N];
vector<E>edge;
bool vis[N];
queue<int>enqueue;

void breadFirstSearch(const int n){
	for(int i=1;i<=n;i++){
		if(!vis[i]){
			enqueue.push(i);
			vis[i]=true;
			while(!enqueue.empty()){
				int num=enqueue.front();
				enqueue.pop();
				for(int j=0;j<G[num].size();j++){
					if(!vis[G[num][j]]){
						vis[G[num][j]]=true;
						struct E temp;
						enqueue.push(G[num][j]);
						temp.u=num;
						temp.v=G[num][j];
						edge.push_back(temp);
					}
				}
			}
		}
	}
	//輸出查找邊集
	for(int i=0;i<edge.size();i++){
		cout<<edge[i].u<<" "<<edge[i].v<<endl;
	}
	return;
}
int main(){

	int n=0,m=0;
	int u=0,v=0;
	
	cin>>n>>m;

	for(int i=1;i<=m;i++){
		cin>>u>>v;
		G[u].push_back(v);	//無向圖
		G[v].push_back(u);
	}

	breadFirstSearch(n);

	return 0;
}

樣例輸入

9 10
1 5
1 6
1 7
1 9
2 7
3 8
4 8
5 6
5 9
6 9

樣例輸出

1 5
1 6
1 7
1 9
7 2
3 8
8 4
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章