最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++圖論核心之最短路徑算法從原理到實(shí)戰(zhàn)

 更新時(shí)間:2026年02月23日 10:41:59   作者:落羽的落羽  
這篇文章主要介紹了C++圖論核心之最短路徑算法,最短路徑問(wèn)題是指,從在帶權(quán)的有向圖中從某一頂點(diǎn)出發(fā),找到通往另一頂點(diǎn)的最短路徑,最短指的是沿路徑各邊的權(quán)值總和最小,需要的朋友可以參考下

一、Dijkstra算法

最短路徑問(wèn)題是指,從在帶權(quán)的有向圖中從某一頂點(diǎn)出發(fā),找到通往另一頂點(diǎn)的最短路徑,“最短”指的是沿路徑各邊的權(quán)值總和最小。

Dijkstra算法是單源最短路徑的經(jīng)典貪心算法,只能用于沒(méi)有負(fù)權(quán)的圖。它從起點(diǎn)出發(fā),每次選當(dāng)前距離最小且未確定最短路徑的節(jié)點(diǎn),用它去松弛(更新)所有鄰接點(diǎn)的最短路徑估計(jì)值,標(biāo)記該節(jié)點(diǎn)為 “已確定”,重復(fù)此過(guò)程直到所有節(jié)點(diǎn)處理完畢,最終得到起點(diǎn)到圖中所有節(jié)點(diǎn)的最短路徑。

// src是選定的起點(diǎn),dist記錄起點(diǎn)到各點(diǎn)的最短路徑,pPath記錄到每個(gè)點(diǎn)的最短路徑的前驅(qū)頂點(diǎn)下標(biāo)
void Dijkstra(const V& src, vector<W>& dist, vector<int>& pPath)
{
		size_t srci = GetVertexIndex(src);
		size_t n = _vertexs.size();
		dist.resize(n, MAX_W);
		pPath.resize(n, -1);
		dist[srci] = 0;
		pPath[srci] = srci;
		// 已經(jīng)確定最短路徑的頂點(diǎn)集合
		vector<bool> S(n, false);
		for (size_t j = 0; j < n; ++j)
		{
			// 選最短路徑頂點(diǎn)且不在S更新其他路徑
			int u = 0;
			W min = MAX_W;
			for (size_t i = 0; i < n; ++i)
			{
				if (S[i] == false && dist[i] < min)
				{
					u = i;
					min = dist[i];
				}
			}
			S[u] = true;
			// 松弛更新u連接頂點(diǎn)v  srci->u + u->v <  srci->v  更新
			for (size_t v = 0; v < n; ++v)
			{
				if (S[v] == false && _matrix[u][v] != MAX_W
					&& dist[u] + _matrix[u][v] < dist[v])
				{
					dist[v] = dist[u] + _matrix[u][v];
					pPath[v] = u;
				}
			}
		}
}

二、Bellman_Ford算法

Bellman_Ford算法能用來(lái)解決負(fù)權(quán)圖的單源最短路徑問(wèn)題,但是它的時(shí)間復(fù)雜度高于Dijkstra算法,本質(zhì)是暴力求解。從起點(diǎn)出發(fā),把圖里所有邊從頭到尾松弛一遍,重復(fù)n次,就能算出起點(diǎn)到所有點(diǎn)的最短路徑;因?yàn)槿魏巫疃搪窂阶疃嘀唤?jīng)過(guò)n?1條邊。跑完之后再掃一遍所有邊,如果還能更新距離,就說(shuō)明圖里有負(fù)權(quán)回路,最短路徑不存在。

bool BellmanFord(const V& src, vector<W>& dist, vector<int>& pPath)
{
		size_t n = _vertexs.size();
		size_t srci = GetVertexIndex(src);
		// vector<W> dist,記錄srci-其他頂點(diǎn)最短路徑權(quán)值數(shù)組
		dist.resize(n, MAX_W);
		// vector<int> pPath 記錄srci-其他頂點(diǎn)最短路徑父頂點(diǎn)數(shù)組
		pPath.resize(n, -1);
		// 先更新srci->srci為缺省值
		dist[srci] = W();
		// 總體最多更新n輪
		for (size_t k = 0; k < n; ++k)
		{
			// i->j 更新松弛
			bool update = false;
			cout << "更新第:" << k << "輪" << endl;
			for (size_t i = 0; i < n; ++i)
			{
				for (size_t j = 0; j < n; ++j)
				{
					// srci -> i + i ->j
					if (_matrix[i][j] != MAX_W && dist[i] != MAX_W && dist[i] + _matrix[i][j] < dist[j])
	 			    {
						update = true;
						//cout << _vertexs[i] << "->" << _vertexs[j] << ":" << _matrix[i][j] << endl;
						dist[j] = dist[i] + _matrix[i][j];
						pPath[j] = i;
					}
				}
			}
			// 如果這個(gè)輪次中沒(méi)有更新出更短路徑,那么后續(xù)輪次就不需要再走了
			if (update == false)
			{
				break;
			}
		}
		// 還能更新就是帶負(fù)權(quán)回路
		for (size_t i = 0; i < n; ++i)
		{
			for (size_t j = 0; j < n; ++j)
			{
				// srci -> i + i ->j
				if (_matrix[i][j] != MAX_W && dist[i] + _matrix[i][j] < dist[j])
				{
					return false;
				}
			}
		}
		return true;
}

三、Floyd_Warshall算法

Floyd-Warshall算法是求任意兩點(diǎn)之間最短路徑的算法,依次把每個(gè)點(diǎn)當(dāng)作中轉(zhuǎn)點(diǎn),判斷從 i 到 j 是直接走更近,還是經(jīng)過(guò)這個(gè)中轉(zhuǎn)點(diǎn) k 再走更近,不斷更新所有點(diǎn)對(duì)的最短距離,三層循環(huán)跑完就得到全圖最短路徑。

void FloydWarshall(vector<vector<W>>& vvDist, vector<vector<int>>& vvpPath)
{
		size_t n = _vertexs.size();
		vvDist.resize(n);
		vvpPath.resize(n);
		// 初始化權(quán)值和路徑矩陣
		for (size_t i = 0; i < n; ++i)
		{
			vvDist[i].resize(n, MAX_W);
			vvpPath[i].resize(n, -1);
		}
		// 直接相連的邊更新一下
		for (size_t i = 0; i < n; ++i)
		{
			for (size_t j = 0; j < n; ++j)
			{
				if (_matrix[i][j] != MAX_W)
				{
					vvDist[i][j] = _matrix[i][j];
					vvpPath[i][j] = i;
				}
				if (i == j)
				{
					vvDist[i][j] = W();
				}
			}
		}
		// 最短路徑的更新i-> {其他頂點(diǎn)} ->j
		for (size_t k = 0; k < n; ++k)
		{
			for (size_t i = 0; i < n; ++i)
			{
				for (size_t j = 0; j < n; ++j)
				{
					// k 作為的中間點(diǎn)嘗試去更新i->j的路徑
					if (vvDist[i][k] != MAX_W && vvDist[k][j] != MAX_W
							&& vvDist[i][k] + vvDist[k][j] < vvDist[i][j])
					{
						vvDist[i][j] = vvDist[i][k] + vvDist[k][j];
							// 找跟j相連的上一個(gè)鄰接頂點(diǎn)
							// 如果k->j 直接相連,上一個(gè)點(diǎn)就k,vvpPath[k][j]存就是k
							// 如果k->j 沒(méi)有直接相連,k->...->x->j,vvpPath[k][j]存就是x
						vvpPath[i][j] = vvpPath[k][j];
					}
				}
			}
		}	
}

以上就是C++圖論核心之最短路徑算法從原理到實(shí)戰(zhàn)的詳細(xì)內(nèi)容,更多關(guān)于C++最短路徑算法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)投票系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)投票系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)投票系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • 使用c語(yǔ)言輸出楊輝三角形的簡(jiǎn)單方法

    使用c語(yǔ)言輸出楊輝三角形的簡(jiǎn)單方法

    這篇文章主要給大家介紹了關(guān)于如何使用c語(yǔ)言輸出楊輝三角形的簡(jiǎn)單方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 關(guān)于C++使用std::chrono獲取當(dāng)前秒級(jí)/毫秒級(jí)/微秒級(jí)/納秒級(jí)時(shí)間戳問(wèn)題

    關(guān)于C++使用std::chrono獲取當(dāng)前秒級(jí)/毫秒級(jí)/微秒級(jí)/納秒級(jí)時(shí)間戳問(wèn)題

    這篇文章主要介紹了C++使用std::chrono獲取當(dāng)前秒級(jí)/毫秒級(jí)/微秒級(jí)/納秒級(jí)時(shí)間戳,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • C語(yǔ)言利用棧實(shí)現(xiàn)對(duì)后綴表達(dá)式的求解

    C語(yǔ)言利用棧實(shí)現(xiàn)對(duì)后綴表達(dá)式的求解

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言利用棧實(shí)現(xiàn)對(duì)后綴表達(dá)式的求解,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • 淺談C語(yǔ)言的變量和常量

    淺談C語(yǔ)言的變量和常量

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言的變量和常量,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-02-02
  • C++實(shí)現(xiàn)歸并排序

    C++實(shí)現(xiàn)歸并排序

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)歸并排序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • MySQL系列教程之使用C語(yǔ)言來(lái)連接數(shù)據(jù)庫(kù)

    MySQL系列教程之使用C語(yǔ)言來(lái)連接數(shù)據(jù)庫(kù)

    c語(yǔ)言操作Mysql數(shù)據(jù)庫(kù),主要就是為了實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的增、刪、改、查等操作,下面這篇文章主要給大家介紹了關(guān)于MySQL系列教程之使用C語(yǔ)言來(lái)連接數(shù)據(jù)庫(kù)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • c語(yǔ)言將字符串中的小寫(xiě)字母轉(zhuǎn)換成大寫(xiě)字母

    c語(yǔ)言將字符串中的小寫(xiě)字母轉(zhuǎn)換成大寫(xiě)字母

    本文主要介紹了c語(yǔ)言將字符串中的小寫(xiě)字母轉(zhuǎn)換成大寫(xiě)字母的方法實(shí)例。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-04-04
  • C語(yǔ)言中強(qiáng)制類型轉(zhuǎn)換的常見(jiàn)方法

    C語(yǔ)言中強(qiáng)制類型轉(zhuǎn)換的常見(jiàn)方法

    強(qiáng)制類型轉(zhuǎn)換是一種將一個(gè)數(shù)據(jù)類型轉(zhuǎn)換為另一個(gè)數(shù)據(jù)類型的方法,這篇文章主要為大家整理了C語(yǔ)言中強(qiáng)制類型轉(zhuǎn)換的方法,需要的可以參考一下
    2023-05-05
  • C++中強(qiáng)類型枚舉(scoped enumeration)的實(shí)現(xiàn)

    C++中強(qiáng)類型枚舉(scoped enumeration)的實(shí)現(xiàn)

    C++11引入的強(qiáng)類型枚舉解決了傳統(tǒng)枚舉的三大缺陷:作用域污染、隱式類型轉(zhuǎn)換和底層類型不確定,本文就來(lái)詳細(xì)的介紹一下強(qiáng)類型枚舉的使用,感興趣的可以了解一下
    2025-11-11

最新評(píng)論

桃园市| 兴海县| 灵寿县| 广灵县| 彰化县| 太白县| 肇东市| 延津县| 太保市| 康定县| 资兴市| 从江县| 买车| 介休市| 淮安市| 甘孜县| 西城区| 法库县| 雷山县| 遂平县| 张北县| 新河县| 滨州市| 长泰县| 青浦区| 定兴县| 修文县| 光山县| 开阳县| 迭部县| 湖口县| 云安县| 和龙市| 新建县| 右玉县| 阿尔山市| 潍坊市| 巴中市| 自贡市| 盐津县| 小金县|