1. 程式人生 > >OJ:最短路徑演算法,Dijk

OJ:最短路徑演算法,Dijk

先構造有向圖,再用Dijk演算法。實現時注意 set 中點的距離的更新。

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <set>

using namespace std;

typedef long long LL;
const int M = 205;
const LL INF = 1E10;

LL a[M];
LL cost[M][M];
LL dist[M];
bool v[M];

int main()
{
	//freopen("data.txt", "r", stdin);
	LL L1, L2, L3, C1, C2, C3, A, B, N;
	while (scanf("%lld %lld %lld %lld %lld %lld %lld %lld %lld", &L1, &L2, &L3, &C1, &C2, &C3, &A, &B, &N) != EOF) {
		memset(v, 0, sizeof(v));
		memset(a, 0, sizeof(a));
		for (int i = 0; i < M; i++) {
			for (int j = 0; j < M; j++) {
				cost[i][j] = INF;
			}
			dist[i] = INF;
		}
		a[1] = 0;
		for (int i = 2; i <= N; i++) {
			scanf("%lld", &a[i]);
		}
		if (A > B) {
			int temp = A;
			A = B;
			B = temp;
		}
		if (A == B) {
			printf("0\n");
			continue;
		}
		for (int i = A; i <= B; i++) {
			cost[i][i] = 0;
			for (int j = i+1; j <= B; j++) {
				LL s = a[j] - a[i];
				if ( s > 0 && s <= L1 ) {
					cost[i][j] = C1;
				} else if (s > L1 && s <= L2) {
					cost[i][j] = C2;
				} else if (s > L2 && s <= L3) {
					cost[i][j] = C3;						
				} else {
					break;
				}
			}
		}
		// Dijk演算法
		set < pair<LL, int> > sdist;
		for (int i = A+1; i <= B; i++) {
			if (cost[A][i] != INF) {
				dist[i] = cost[A][i];
				sdist.insert( make_pair(dist[i], i) );
				v[i] = true;
			}
		}
		while (!sdist.empty()) {
			int next = ( sdist.begin() )->second;
			LL mincost = ( sdist.begin() )->first;
			sdist.erase(sdist.begin());
			dist[next] = mincost;	// 確定一點最短路徑
			if (next == B) {
				printf("%lld\n", dist[B]);
				break;
			} else {	// 更新與next相鄰的點的距離
				for (int i = next+1; i <= B; i++) {	// next != B
					if (dist[i] > dist[next] + cost[next][i]) {
						if (!v[i]) {
							dist[i] = dist[next] + cost[next][i];
							sdist.insert( make_pair(dist[i], i) );
							v[i] = true;
						} else {
							set < pair<LL, int> >::iterator it;
							it = sdist.find( make_pair(dist[i], i) );
							if (it != sdist.end()) {
								sdist.erase(it);
								dist[i] = dist[next] + cost[next][i];
								sdist.insert( make_pair(dist[i], i) );
							}
						}
					}
				}
			}
		}
	}

	return 0;
}


相關推薦

OJ路徑演算法Dijk

先構造有向圖,再用Dijk演算法。實現時注意 set 中點的距離的更新。 #include <stdio.h> #include <string.h> #include <algorithm> #include <set>

圖論四路徑演算法

一、廣度優先搜尋 1、思路:距離開始點最近的點首先被賦值,最遠的點最後被賦值。 2、適用範圍:對於非負數權的無圈圖來說(單源最短路徑)。 3、演算法實現: (1)一個佇列記錄每個每個節點的編號。 (2)將起始節點入隊,將所有節點到起始節點的距離設定為無窮大,起始節點到起始節點的距離為0; (3)取

演算法8-10路徑演算法之拓撲排序

該演算法的基本思想就是按照拓撲排序的順序依次將每個頂點加入到最短路徑樹中,每次加入時將該頂點延伸出的所有頂點進行“放鬆”操作。這種演算法的複雜度是E+V。 程式碼 這種演算法的程式碼比Dijkstra還要簡單,程式碼如下: public class Topology

九度 OJ 題目1008路徑問題 (Dijstra 演算法

題目描述: 給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。 輸入: 輸入n,m,點的編號是1~n,然後是m行,每行4個數 a,b,d,p,表示a和b之間有一條邊,且其長度為

問題 1708: 演算法7-15迪傑斯特拉路徑演算法

題目描述 在帶權有向圖G中,給定一個源點v,求從v到G中的其餘各頂點的最短路徑問題,叫做單源點的最短路徑問題。 在常用的單源點最短路徑演算法中,迪傑斯特拉演算法是最為常用的一種,是一種按照路徑長度遞增的次序產生最短路徑的演算法。 可將迪傑斯特拉演算法描述如下: 在本題中,讀

Codeup 問題 B: 演算法7-16弗洛伊德路徑演算法

題目描述 在帶權有向圖G中,求G中的任意一對頂點間的最短路徑問題,也是十分常見的一種問題。 解決這個問題的一個方法是執行n次迪傑斯特拉演算法,這樣就可以求出每一對頂點間的最短路徑,執行的時間複雜度為O(n3)。 而另一種演算法是由弗洛伊德提出的,時間複雜度同樣是O(n3

演算法7-15迪傑斯特拉路徑演算法

題目描述 在帶權有向圖G中,給定一個源點v,求從v到G中的其餘各頂點的最短路徑問題,叫做單源點的最短路徑問題。 在常用的單源點最短路徑演算法中,迪傑斯特拉演算法是最為常用的一種,是一種按照路徑長度遞增的次序產生最短路徑的演算法。 可將迪傑斯特拉演算法描述如下:

演算法7-15迪傑斯特拉路徑演算法(c語言)

題目描述 在帶權有向圖G中,給定一個源點v,求從v到G中的其餘各頂點的最短路徑問題,叫做單源點的最短路徑問題。 在常用的單源點最短路徑演算法中,迪傑斯特拉演算法是最為常用的一種,是一種按照路徑長度遞增的次序產生最短路徑的演算法。 可將迪傑斯特拉演算法描述如下: 在本題中,讀入

A.pro讀演算法の11路徑之Dijkstra演算法

此文是獻給OIer看的。講的東西比較基礎(其實我理解Dijkstra花了很長時間)。NOIP2018結束約有1個月了,但是我們仍要繼續前進,為NOIP2019做準備。本節學習Dijkstra的演算法思想和實現,以及優先佇列和堆優化。線段樹也可以做到優化,甚至可能還更快,但是我太弱了不會。。

演算法7-15迪傑斯特拉路徑演算法(模板)

題目描述 在帶權有向圖G中,給定一個源點v,求從v到G中的其餘各頂點的最短路徑問題,叫做單源點的最短路徑問題。 在常用的單源點最短路徑演算法中,迪傑斯特拉演算法是最為常用的一種,是一種按照路徑長度遞增的次序產生最短路徑的演算法。 在本題中,讀入一個有向圖的帶權鄰接矩陣(即陣列

演算法7-16弗洛伊德路徑演算法(模板)

題目描述 在帶權有向圖G中,求G中的任意一對頂點間的最短路徑問題,也是十分常見的一種問題。 解決這個問題的一個方法是執行n次迪傑斯特拉演算法,這樣就可以求出每一對頂點間的最短路徑,執行的時間複雜度為O(n3)。 而另一種演算法是由弗洛伊德提出的,時間複雜度同樣是O(n3),但

問題 F: 演算法7-15迪傑斯特拉路徑演算法

題目描述 在帶權有向圖G中,給定一個源點v,求從v到G中的其餘各頂點的最短路徑問題,叫做單源點的最短路徑問題。 在常用的單源點最短路徑演算法中,迪傑斯特拉演算法是最為常用的一種,是一種按照路徑長度遞增的次序產生最短路徑的演算法。 在本題中,讀入一個有向圖的帶權鄰接矩陣(

演算法7-16弗洛伊德路徑演算法

題目描述 在帶權有向圖G中,求G中的任意一對頂點間的最短路徑問題,也是十分常見的一種問題。 解決這個問題的一個方法是執行n次迪傑斯特拉演算法,這樣就可以求出每一對頂點間的最短路徑,執行的時間複雜度為O(n3)。 而另一種演算法是由弗洛伊德提出的,時間複雜度同樣是O(n3

codeup 問題 B: 演算法7-16弗洛伊德路徑演算法

                                 問題 B: 演算法7-16:弗洛伊德最短路徑演算法                                                                時間限制: 1 Sec  記憶

路徑演算法克魯斯卡爾演算法和迪傑斯特拉演算法(天勤資料結構高分筆記)

迪傑斯特拉演算法演算法思想:     設有兩個頂點集合S和T,集合S存放途中已經找到最短路徑的頂點,集合T存放的是途中剩餘頂點。初始狀態是,集合S只包含源點V0,然後不斷從集合T中     選取到頂點V0的路徑長度最短的頂點Vu併入到初始集合中。集合S每併入一個新的頂點Vu,

圖論經典演算法(通俗易懂)路徑小生成樹

一、最短路問題 求圖的最短路問題,幾乎是圖論的必學內容,而且在演算法分析與設計中也會涉及。很多書上內容, 實在沒法看,我們的圖論教材,更是編的非常糟糕,吐槽,為啥要用自己學校編的破教材,不過據說 下一屆終於要換書了。 言歸正傳,開始說明最短路問題。

單源點路徑演算法Dijkstra演算法

背景知識 圖簡介 圖由節點和邊組成,邊有方向的圖稱為有向圖,邊沒有方向的圖稱為無向圖,最短路徑演算法裡可以把無向圖視為雙向連線的有向圖。 邊有權重的圖稱為有權圖,邊沒有權重的圖稱為無權圖,無權圖可以視為邊的權重均為1的圖。 單源點最短路徑 給定

圖論圖的四種路徑演算法

本文總結了圖的幾種最短路徑演算法的實現:深度或廣度優先搜尋演算法,弗洛伊德演算法,迪傑斯特拉演算法,Bellman-Ford演算法1),深度或廣度優先搜尋演算法(解決單源最短路徑)從起始結點開始訪問所有的深度遍歷路徑或廣度優先路徑,則到達終點結點的路徑有多條,取其中路徑權值最

圖的路徑演算法(DijkstraFloyd)的實現

從某個源點到其餘各頂點的最短路徑 迪杰特斯拉演算法 Dijkstra(迪傑斯特拉)演算法是典型的單源最短路徑演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。 演算法步驟如下:

圖論演算法路徑——無權路徑演算法和Dijkstra演算法C++實現

前言        今天將給大家介紹的是圖論演算法中的另外一個基礎部分——最短路徑演算法;其中又分為無權最短路徑,單源最短路徑,具有負邊的最短路徑以及無圈圖等;而這次將介紹常見的兩個——無權最短路徑以及單源最短路徑。接下來就開始我們的講解吧~~原理        最短路徑演算