《算法笔记》学习记录 Part 4 图(中)

第十章    数据结构专题 —— 图(中)

10.4 最短路径

对任意给出的图G(V,E)和起点S、终点T,如何求S到T的最短路径,解决最短路径问题的常用算法有Dijkstra算法,SPFA算法、Bellman-Ford算法、Floyd算法

10.4.1 Dijkstra算法

Dijkstra算法用来解决单源最短路径问题,即给定图G和起点S,通过算法得到S到其他每个顶点的最短距离。

const int MAXV = 1000;
const int INF = 1000000000;

//邻接矩阵版,适用于点数不打(V不超过1000)的情况。相对好写
int n,G[MAXV][MAXV];		//n为顶点数,MAXV为最大顶点数
int d[MAXV];	//起点到达各个点的最短路径长度
bool vis[MAXV] = {false};	//标记数组,vis[i]==true表示已经访问

void Dijkstra(int s){		//s为起点
	fill(d,d+MAXV,INF);	//fill函数将整个d数组赋值为INF
	d[s]=0;	//起点s到达自身的距离为0
	for(int i=0;i


//邻接表版
struct Node{
	int v,dis;	//v为边的目标顶点,dis为边权
};

vector Adj[MAXV];
int n;
int d[MAXV];
bool vis[MAXV] = {false};

void Dijkstra(int s){
	fill(d,d+MAXV,INF);
	d[s]=0;
	for(int i=0;i

10.4.3 Floyd算法

Floyd用来解决全源最短路径,即对给定的图G(V,E),求任意两点u,v之间的最短路径长度,时间复杂度为O(n3),这个复杂度决定了顶点数n的限制约在200以内,因此使用邻接矩阵来实现Floyd算法是非常合适且方便的

#include 
#include 
using namespace std;

const int INF = 10000000000;
const int MAXV = 200;	//MAXV为最大顶点数
int n,m;		//n为顶点数,m为边数
int dis[MAXV][MAXV];			//dis[i][j]表示顶点i和顶点j的最短距离

void Floyd(){
	for(int k=0;k

10.5 最小生成树(MST)

Minimum Spanning Tree , MST 是在一个给定的无向图 G(V,E)中求一棵树T,使得这棵树拥有图G中的所有顶点,且所有边都是来自图G中的边,并且满足整棵树的边权之和最小

10.5.1 Prim算法

适合稠密图,加点法

const int MAXV = 1000;
const int INF = 1000000000;

//邻接矩阵版
int n,G[MAXV][MAXV];
int d[MAXV]; 	//顶点与集合s的最短距离
bool vis[MAXV] = {false};

int prim(){		//默认0号位初始点,函数返回最小生成树的边权之和
	fill(d,d+MAXV,INF);
	d[0]=0;
	int ans=0;	//存放最小生成树的边权之和
	for(int i=0;i
//邻接表版
struct Node{
	int v,dis;	//v为边的目标顶点,dis为边权
};
vector Adj[MAXV];
int n;
int d[MAXV];
bool vis[MAXV] = {false};

int Prim(){
	fill(d,d+MAXV,INF);
	d[0]=0;
	int ans = 0;
	for(int i=0;i

10.5.2 Kruskal算法

Kruskal算法采用了边贪心的策略,其思想极其简洁,理解难度比Prim算法低很多

如果是稀疏图,边少,适用于Kruskal,加边法

#include 
#include 
using namespace std;
const int MAXV = 110;
const int MAXE = 10010;

//边集定义部分
struct edge{
	int u,v;		//边的两个端点编号
	int cost; 	//边权
}E[MAXE];	//最多有MAXE条边

bool cmp(edge a,edge b){
	return a.cost





你可能感兴趣的:(C++)