国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

求最短路徑的三種算法

這篇具有很好參考價(jià)值的文章主要介紹了求最短路徑的三種算法。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目錄

一.單源最短路

1.dijkstra算法及實(shí)現(xiàn)

2.spfa算法及實(shí)現(xiàn)

(1)spafa負(fù)環(huán)判斷及實(shí)現(xiàn)

二.多源最短路

1.floyd算法及實(shí)現(xiàn)

一.單源最短路

1.dijkstra算法及實(shí)現(xiàn)
求源點(diǎn)到圖中其余各頂點(diǎn)的最短路徑
dfs效率慢,解決規(guī)模小,bfs只能邊權(quán)為1的圖
Dijkstra算法——迪杰斯塔拉算法(非負(fù)全圖)
?基本思想:
?首先假定源點(diǎn)為u,頂點(diǎn)集合V被劃分為兩部分:集合 S 和 V-S.
?初始時(shí)S中僅含有源點(diǎn)u,其中S中的頂點(diǎn)到源點(diǎn)的最短路徑已經(jīng)確定。
集合S 和V - S中所包含的頂點(diǎn)到源點(diǎn)的最短路徑的長(zhǎng)度待定,
?稱從源點(diǎn)出發(fā)只經(jīng)過S中的點(diǎn)到達(dá)V - S中的點(diǎn)的路徑為特殊路徑,
并用dist[]記錄當(dāng)前每個(gè)頂點(diǎn)對(duì)應(yīng)的最短特殊路徑長(zhǎng)度。
實(shí)現(xiàn)從1到n的最短路徑
?輸入:
3 3
1 2 5
2 3 5
3 1 2
輸出:
2

#include<iostream>
#include<cstring>
using namespace std;
const int N = 1001;
const int M = 10001;
int head[N];
int size1;
int n, m;
struct edge {
	int v, w, next;
	edge() {};
	edge(int _v, int _w, int _next) {
		v = _v;
		w = _w;
		next = _next;
	}
}e[M*2];
void init() {
	memset(head, -1, sizeof(head));
	size1 = 0;;

}
void insert(int u,int v,int w) {
	e[size1] = edge(v, w, head[u]);
	head[u] = size1++;
}
void insert2(int u, int v, int w) {
	insert(u, v, w);
	insert(v, u, w);
}
int dis[N];
bool vis[N];
void dijkstra(int u)
{
	memset(vis, false, sizeof(vis));
	memset(dis, 0x3f, sizeof(dis));       //0x3f用以表示正無(wú)窮
	dis[u] = 0; 
	int mind = 1000000000;
	for (int i = 0; i < n; i++) {
		int minj = -1;
		for (int j = 1; j <= n; j++) {
			if (!vis[j] && dis[j] < mind) {
				minj = j;
				mind = dis[j];
			}
		}
		if (minj == -1)
			return;
		vis[minj] = true;
		for (int j = head[minj];~j ; j = e[j].next) {  ///~j等價(jià)于j!=-1;
			int v = e[j].v;
			int w = e[j].w;
			if (!vis[v] && dis[v] > dis[minj] + w)
				dis[v] = dis[minj] + w;
		}
	}
}
int main()
{
	init();
	int u, v, w;
	cin >> n >> m;
	while (m--) {
		cin >> u >> v >> w;
		insert2(u, v, w);
	}
	dijkstra(1);
	cout << dis[n] << endl;
	return 0;
}


2.SPFA算法——Shortest Path Faster Algorithm?
思路:
用數(shù)組dis記錄每個(gè)結(jié)點(diǎn)的最短路徑估計(jì)值,用鄰接表或鄰接矩陣來存儲(chǔ)圖G。
我們采取的方法是動(dòng)態(tài)逼近法:設(shè)立一個(gè)先進(jìn)先出的隊(duì)列用來保存待優(yōu)化的結(jié)點(diǎn),
優(yōu)化時(shí)每次取出隊(duì)首結(jié)點(diǎn)u,
并且用u點(diǎn)當(dāng)前的最短路徑估計(jì)值對(duì)離開u點(diǎn)所指向的結(jié)點(diǎn)v進(jìn)行松弛操作,
如果v點(diǎn)的最短路徑估計(jì)值有所調(diào)整,且v點(diǎn)不在當(dāng)前的隊(duì)列中,就將v點(diǎn)放入隊(duì)尾。
這樣不斷從隊(duì)列中取出結(jié)點(diǎn)來進(jìn)行松弛操作,直至隊(duì)列空為止
優(yōu)點(diǎn):
(可以解決帶負(fù)權(quán)的有向圖并且在稀疏圖優(yōu)于dijsktra)
反例:
?1.出題特殊數(shù)據(jù)使SPFA算法慢,2.有負(fù)環(huán)不能解決
推薦后續(xù)優(yōu)化的dijkstra算法
實(shí)現(xiàn):

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N = 1001;
const int M = 10001;
int head[N];
int size1;
int n, m;
struct edge {
	int v, w, next;
	edge() {};
	edge(int _v, int _w, int _next) {
		v = _v;
		w = _w;
		next = _next;
	}
}e[M*2];
void init() {
	memset(head, -1, sizeof(head));
	size1 = 0;;

}
void insert(int u,int v,int w) {
	e[size1] = edge(v, w, head[u]);
	head[u] = size1++;
}
void insert2(int u, int v, int w) {
	insert(u, v, w);
	insert(v, u, w);
}
int dis[N];
bool vis[N];
void spfa(int u) {
	memset(vis, false, sizeof(vis));
	vis[u] = true;
	memset(dis, 0x3f, sizeof(dis));
	dis[u] = 0;
	queue<int>q;
	q.push(u);
	while (!q.empty()) {
		u = q.front();
		q.pop();
		vis[u] = false;
		for (int j = head[u]; ~j; j = e[j].next) {
			int v = e[j].v;
			int w = e[j].w;
			if (dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				if (!vis[v]) {
					q.push(v);
					vis[v] = true;
				}
			}

		}
	}
}
int main()
{
	init();
	int u, v, w;
	cin >> n >> m;
	while (m--) {
		cin >> u >> v >> w;
		insert2(u, v, w);
	}
	spfa(1);
	cout << dis[n] << endl;
	return 0;
}


(1)spfa判斷負(fù)環(huán)
在進(jìn)行spfa用一個(gè)數(shù)組cnt標(biāo)記每個(gè)頂點(diǎn)的入隊(duì)次數(shù),如果一個(gè)頂點(diǎn)的入隊(duì)次數(shù)大于頂點(diǎn)總數(shù)
則表示該圖含有負(fù)環(huán)

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N = 1001;
const int M = 10001;
int head[N];
int size1;
int n, m;
struct edge {
	int v, w, next;
	edge() {};
	edge(int _v, int _w, int _next) {
		v = _v;
		w = _w;
		next = _next;
	}
}e[M*2];
void init() {
	memset(head, -1, sizeof(head));
	size1 = 0;;

}
void insert(int u,int v,int w) {
	e[size1] = edge(v, w, head[u]);
	head[u] = size1++;
}
void insert2(int u, int v, int w) {
	insert(u, v, w);
	insert(v, u, w);
}
int dis[N], in[N];
bool vis[N];
bool spfa(int u) {
	memset(vis, false, sizeof(vis));
	vis[u] = true;
	memset(dis, 0x3f, sizeof(dis));
	dis[u] = 0;
	memset(in, 0, sizeof(in));
	in[u] = u;
	queue<int>q;
	q.push(u);
	while (!q.empty()) {
		u = q.front();
		q.pop();
		vis[u] = false;
		for (int j = head[u]; ~j; j = e[j].next) {
			int v = e[j].v;
			int w = e[j].w;
			if (dis[v] > dis[u] + w)
				dis[v] = dis[u] + w;
			if (!vis[v]) {
				q.push(v);
				vis[v] = false;
				++in[v];
				if (in[v] > n)
					return true;
			}
		}
	}
	return false;
}
int main()
{
	init();
	int u, v, w;
	cin >> n >> m;
	while (m--) {
		cin >> u >> v >> w;
		insert2(u, v, w);
	}
	if (spfa(1))
		cout << "Yes" << endl;
	else
		cout << "No" << endl;
	return 0;
}


二.多源最短路
1.floyd算法——(Floyd-Warshall algorithm),中文亦稱弗洛伊德算法
利用動(dòng)態(tài)規(guī)劃的思想解決帶權(quán)圖中任意兩個(gè)點(diǎn)之間最短路徑算法
優(yōu)勢(shì):代碼簡(jiǎn)短,高效,可以解決帶負(fù)權(quán)

反例:不能解決帶負(fù)環(huán)
思路:
dp[0][i][j]=圖
dp[k][i][j]=從i到j(luò)可能經(jīng)過1...k最短路徑,
min(dp[k][i][j],dp[k-1][i][k]+dp[k-1][k][j])
優(yōu)化為二維:
min(dp[i][j],dp[i][k]+dp[k][j])
實(shí)現(xiàn):
?文章來源地址http://www.zghlxwxcb.cn/news/detail-619878.html

#include<iostream>
#include<cstring>
using namespace std;
const int N = 101;
int g[N][N];
void floyd(int n) {
	for (int k = 1; k <= n; k++) {
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				g[i][j] = min(g[i][j], g[i][k] + g[j][k]);
			}
		}
	}
}
int main()
{
	memset(g, 0x3f, sizeof(g));
	for (int i = 0; i < N; i++) {
		g[i][i] = 0;
	}
	int n, m;
	int u, v, w;
	cin >> n >> m;
	while (m--) {
		cin >> u >> v >> w;
		g[u][v] = g[v][u] = w;
	}
	floyd(n);
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			cout << g[i][j] << ' ';
		}
		cout << endl;
	}
	return 0;
}

到了這里,關(guān)于求最短路徑的三種算法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【圖論算法】深度優(yōu)先搜索的應(yīng)用

    【圖論算法】深度優(yōu)先搜索的應(yīng)用

    深度優(yōu)先搜索 (depth-first search)是對(duì)先序遍歷(preorder traversal)的推廣。我們從某個(gè)頂點(diǎn) v 開始處理 v,然后遞歸地遍歷所有鄰接到 v 的頂點(diǎn)。 對(duì)一棵樹的所有頂點(diǎn)的訪問需 O(|E|) 時(shí)間。對(duì)任意圖進(jìn)行該過程時(shí)則需要考慮避免圈的出現(xiàn)。為此,當(dāng)訪問一個(gè)頂點(diǎn) v 的時(shí)候,由于當(dāng)時(shí)已

    2024年02月08日
    瀏覽(90)
  • Python 圖算法,圖最短路徑,圖廣度優(yōu)先搜索,圖深度優(yōu)先搜索,圖排序

    一、圖數(shù)據(jù)庫(kù)相關(guān)算法 圖數(shù)據(jù)庫(kù)是一種專門用來存儲(chǔ)和處理圖數(shù)據(jù)的數(shù)據(jù)庫(kù)系統(tǒng)。它使用圖結(jié)構(gòu)來表示數(shù)據(jù)之間的關(guān)聯(lián)關(guān)系,以及節(jié)點(diǎn)和邊之間的屬性信息。以下是一些常用的圖數(shù)據(jù)庫(kù)算法: 1. 最短路徑算法:最短路徑算法用于計(jì)算圖中兩個(gè)節(jié)點(diǎn)之間的最短路徑,例如Dijk

    2024年02月15日
    瀏覽(22)
  • 【算法】求最短路徑算法

    【算法】求最短路徑算法

    從某頂點(diǎn)出發(fā),沿圖的邊到達(dá)另一頂點(diǎn)所經(jīng)過的路徑中,各邊上權(quán)值之和最小的一條路徑叫做最短路徑。 解決最短路徑的問題有以下算法:Dijkstra 算法,Bellman-Ford 算法,F(xiàn)loyd 算法和 SPFA 算法等。 迪杰斯特拉算法(Dijkstra 算法)是典型最短路徑算法,用于計(jì)算一個(gè)節(jié)點(diǎn)到其它

    2024年02月02日
    瀏覽(18)
  • 圖論與算法(3)圖的深度優(yōu)先遍歷

    圖論與算法(3)圖的深度優(yōu)先遍歷

    圖的遍歷 是指按照一定規(guī)則訪問圖中的所有頂點(diǎn),以便獲取圖的信息或執(zhí)行特定操作。常見的圖遍歷算法包括深度優(yōu)先搜索(DFS)和廣度優(yōu)先搜索(BFS)。 深度優(yōu)先搜索 (DFS):從起始頂點(diǎn)開始,遞歸或使用棧的方式訪問相鄰的頂點(diǎn),直到所有頂點(diǎn)都被訪問過為止。DFS通過

    2024年02月06日
    瀏覽(27)
  • c語(yǔ)言寫鄰接矩陣的最短路徑的Dijkstra算法(附有詳細(xì)代碼)

    c語(yǔ)言寫鄰接矩陣的最短路徑的Dijkstra算法(附有詳細(xì)代碼)

    (1) 用dis數(shù)組來存儲(chǔ)源點(diǎn)1到其他頂點(diǎn)的初始路徑,標(biāo)記1號(hào)頂點(diǎn), 此時(shí)dis數(shù)組中的值稱為最短路徑的估計(jì)值。 (2) 從dis數(shù)組中找出離源起點(diǎn)最近的點(diǎn)2號(hào),以2號(hào)頂點(diǎn)為源點(diǎn)進(jìn)行找最近的頂點(diǎn)。把2號(hào)頂點(diǎn)標(biāo)記,表示已經(jīng)有最小值。 以2號(hào)頂點(diǎn)為源點(diǎn),看2號(hào)頂點(diǎn)有哪些出邊,看能不

    2024年02月05日
    瀏覽(30)
  • 圖算法——求最短路徑(Floyd算法)

    圖算法——求最短路徑(Floyd算法)

    目錄 一、什么是最短路徑 二、弗洛伊德(Floyd)算法 三、測(cè)試程序 ????????求圖的最短路徑在實(shí)際生活中有許多應(yīng)用,比如說在你在一個(gè)景區(qū)的某個(gè)景點(diǎn),參觀完后,要怎么走最少的路程到你想?yún)⒂^的下個(gè)景點(diǎn),這就利用到了求圖最短路徑的算法。求圖的最短路徑有很多

    2024年02月07日
    瀏覽(24)
  • 圖算法——求最短路徑(Dijkstra算法)

    圖算法——求最短路徑(Dijkstra算法)

    ? ? ? ? 目錄 一、什么是最短路徑 二、迪杰斯特拉(Dijkstra)算法 ?三、應(yīng)用Dijkstra算法 (1) Dijkstra算法函數(shù)分析 ????????求圖的最短路徑在實(shí)際生活中有許多應(yīng)用,比如說在你在一個(gè)景區(qū)的某個(gè)景點(diǎn),參觀完后,要怎么走最少的路程到你想?yún)⒂^的下個(gè)景點(diǎn),這就利用到

    2023年04月15日
    瀏覽(20)
  • Dijkstra算法求最短路

    Dijkstra算法求最短路

    Dijkstra算法的流程如下: 1.初始化dist[1] = 0,其余節(jié)點(diǎn)的dist值為無(wú)窮大。 2.找出一個(gè)未被標(biāo)記的、dist[x]最小的節(jié)點(diǎn)x,然后標(biāo)記節(jié)點(diǎn)x。 3.掃描節(jié)點(diǎn)x的所有出邊(x,y,z),若dist[y] dist[x] + z,則使用dist[x] + z更新dist[y]。 4.重復(fù)上述2~3兩個(gè)步驟,直到所有的節(jié)點(diǎn)都被標(biāo)記。 Dijk

    2024年02月06日
    瀏覽(20)
  • 迪杰斯特拉算法(求最短路徑)

    迪杰斯特拉算法(求最短路徑)

    迪杰斯特拉算法用于查找圖中某個(gè)頂點(diǎn)到其它所有頂點(diǎn)的最短路徑,該算法既適用于無(wú)向加權(quán)圖,也適用于有向加權(quán)圖。 注意,使用迪杰斯特拉算法查找最短路徑時(shí),必須保證圖中所有邊的權(quán)值為非負(fù)數(shù),否則查找過程很容易出錯(cuò)。 迪杰斯特拉算法的實(shí)現(xiàn)思路 圖 1 是一個(gè)無(wú)

    2024年02月02日
    瀏覽(21)
  • 弗洛伊德算法(求最短路徑)

    弗洛伊德算法(求最短路徑)

    在一個(gè)加權(quán)圖中,如果想找到各個(gè)頂點(diǎn)之間的最短路徑,可以考慮使用弗洛伊德算法。 弗洛伊德算法既適用于無(wú)向加權(quán)圖,也適用于有向加權(quán)圖。使用弗洛伊德算法查找最短路徑時(shí),只允許環(huán)路的權(quán)值為負(fù)數(shù),其它路徑的權(quán)值必須為非負(fù)數(shù),否則算法執(zhí)行過程會(huì)出錯(cuò)。 弗洛

    2024年02月06日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包