图算法专题 存储方式,遍历,最短路径

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;

const int maxv = 1000;//最大定点数
const int INF = 1000000000;

//------------------------------------------------
//dfs遍历图,邻接矩阵版
//------------------------------------------------
int n, G[maxv][maxv];
bool vis[maxv] = { false };

void dfs(int u, int depth) {
	vis[u] = true;
	for (int v = 0; v < n; v++) {
		if (G[u][v] != INF && vis[v] == false) {
			dfs(v, depth + 1);
		}
	}
}

//遍历图
void dfsTrave() {
	for (int i = 0; i < n; i++) {
		if (vis[i] == false) {
			dfs(i, 1);
		}
	}
}

//------------------------------------------------
//dfs遍历图,邻接表版
//------------------------------------------------
vector<int> Adj[maxv];
void dfs(int u, int depth) {
	vis[u] = true;
	for (int i = 0; i < Adj[u].size(); i++) {
		int v = Adj[u][i];
		if (vis[v] == false) {
			dfs(v, depth + 1);
		}
	}
}

void dfsTrave() {
	for (int i = 0; i < n; i++) {
		if (vis[i] == false) {
			dfs(i, 1);
		}
	}
}

//------------------------------------------------
//bfs遍历图,邻接表版
//------------------------------------------------
#include<queue>
bool inq[maxv]={ false };
void bfs(int u) {
	queue<int> q;
	q.push(u);
	inq[u] = true;
	while (!q.empty()) {
		int u = q.front();
		q.pop();
		for (int i = 0; i < n; i++) {
			if (inq[i] == false && G[u][i] != INF) {
				q.push(i);
				inq[i] = true;
			}
		}
	}
}

void bfsTrave() {
	for (int i = 0; i < n; i++) {
		if (inq[i] == false) {
			bfs(i);
		}
	}
}

//------------------------------------------------
//bfs遍历图,邻接矩阵
//------------------------------------------------
vector<int> Adj[maxv];

void bfs(int u) {
	queue<int> q;
	q.push(u);
	inq[u] = true;
	while (!q.empty) {
		int u = q.front();
		q.pop();
		for (int i = 0; i < Adj[u].size(); i++) {
			int v = q.front;
			q.pop();
			if (inq[v] == false) {
				q.push(v);
				inq[v] = true;
			}   

		}
	}
}

void bfsTrave() {
	for (int i = 0; i < n; i++) {
		if (inq[i] == false) {
			bfs(i);
		 }
	}
}

迪杰斯特拉算法算单源最短路径:
伪代码:
在这里插入图片描述


const int maxv = 1000;//最大节点数
const int INF = 1000000000;
//--------------------------------------------
//邻接矩阵版
//--------------------------------------------
int n, G[maxv][maxv];
int d[maxv];//从顶点到各个点的最短路径长度
bool vis[maxv] = { false };//标记已确定数组

void Dijkstra(int s) {//s为起点
	fill(d, d + maxv, INF);
	d[s] = 0;//起点s到自身距离为0
	for (int i = 0; i < n; i++) {//循环n次
		int u = -1, MIN = INF;
		for (int j = 0; j < n; j++) {//找未访问顶点d[]中最小的
			if (vis[j] == false && d[j] < MIN) {
				MIN = d[j];
				u = j;
			}
		}
		if (u == -1) {
			//找不到小于INF的d[u]说明剩下的顶点与起点不连通
			return;
		}
		vis[u] = true;//标记u为已访问
		for (int v = 0; v < n; v++) {//如果经过u到达v比之前v的最小距离小,更新
			if (vis[v] == false && G[u][v] != INF && d[u] + G[u][v] < d[v]) {
				d[v] = d[u] + G[u][v];
			}
		}
	}
}

//--------------------------------------------
//邻接表版
//--------------------------------------------
struct Node {
	int v, dis;//v编号dis边权
};
vector<Node> Adj[maxv];//n d vis用上一个的
void Dijkstra2(int s) {
	fill(d, d + maxv, INF);
	d[s] = 0;
	for (int i = 0; i < n; i++) {//循环n次
		//找未访问中最小距离城市
		int MIN = INF, u = -1;
		for (int j = 0; j < n; j++) {
			if (vis[j] == false && d[j] < MIN) {
				MIN = d[j];
				u = j;
			}
		}
		if (u == -1)return;
		vis[u] = true;
		for (int j = 0; j < Adj[u].size(); j++) {
			int v = Adj[u][j].v;//获取当前邻居
			if (vis[v] == false && d[u] + Adj[u][j].dis < d[v]) {
				d[v] = d[u] + Adj[u][j].dis;
			}
		}
	}
}

Dijkstra+DFS解决多尺度问题

using namespace std;

const int INF = 1000000000;
const int maxv = 510;
vector<int> pre[maxv];
int d[maxv], n, vis[maxv], G[maxv][maxv];

void Dijkstra(int s) {
	fill(d, d + maxv,INF);
	d[s] = 0;
	for (int i = 0; i < n; i++) {
		int u = -1, MIN = INF;
		for (int j = 0; j < n; j++) {
			if (vis[j] == false && d[j] < MIN) {
				MIN = d[j];
				u = j;
			}
		}
		if (u == -1)return;
		vis[u] = true;
		for (int v = 0; v < n; v++) {
			if (vis[v] == false && G[u][v] != INF) {
				if (d[u] + G[u][v] < d[v]) {
					d[v] = d[u] + G[u][v];
					pre[v].clear();
					pre[v].push_back(u);//令v的前驱为u
				}
				else if (d[u] + G[u][v] == d[v]) {
					pre[v].push_back(u);
				}
			}
		}
	}
}

int optvalue;//第二标尺最优
vector<int> path, tempPath;//最优路径和临时路径
int st;//起点
void DFS(int v) {
	//递归边界
	if (v == st) {//如果到达叶子节点st,即路径起点
		tempPath.push_back(v);//讲起点加入
		int value;//存放临时路径tempPath的第二标尺的值
		//这里计算tempPath上的value
		if (value > optvalue) {
			optvalue = value;
			path = tempPath;
		}
		tempPath.pop_back();//将刚加入的节点删除
		return;
	}
	//递归
	tempPath.push_back(v);
	for (int i = 0; i < pre[v].size; i++) {
		DFS(pre[v][i]);
	}
	tempPath.pop_back();//遍历完所有前驱节点,将当前节点v删除
}

猜你喜欢

转载自blog.csdn.net/weixin_42189888/article/details/106673035