先用floyd預處理各個點小道的距離,每個點有兩個狀態:從小道到達d1[u]
和從大道到達d2[u]
。轉移方式為:
d1[u]:d2[v]+w; 大道到達的點+小道
d2[u]: d2[u]+w; 大道到達的點+大道
d2[u]: d1[v]+w; 小道到達的點+大道
為什麼小道的點不能從小道到達的點+小道呢?
因為我們已經預處理過了,比如u->v->w,其中(u,v),(v,w)都是小道,u是大道到達的點,d[w] = d[v]+w;的話是不正確的,因為連續走了兩條小道。所以,小道到達的點一定是從乙個大道到達的點走一連串小道到達的。
#include
using
namespace std;
#define for0(a,b) for(int i = a; i < b; ++i)
#define fore(a,b) for(int i = a; i <= b; ++i)
typedef
long
long ll;
typedef pair<
int,
int> pii;
const
int maxn =
500+5;
const ll inf =
1e18
;int n,m;
ll g1[maxn]
[maxn]
,g2[maxn]
[maxn]
;ll d1[maxn]
,d2[maxn]
;int cnt[maxn]
, inq[maxn]
;void
spfa()
}if(d2[i]
> d1[u]
+g2[u]
[i])}}
if(g1[u]
[i]!= inf)}}
}}cout <<
min(d1[n]
,d2[n]
)<< endl;
}int
main()
}int t,a,b,c;
for(
int i =
0; i < m;
++i)
for(
int i =
1; i <= n;
++i)
for(
int j = i+
1; j <= n;
++j)
for(
int k =
1; k <= n;
++k)
spfa()
;return0;
}
CCF 2017 12 4 行車路線(最短路變形)
小明和小芳出去鄉村玩,小明負責開車,小芳來導航。小芳將可能的道路分為大道和小道。大道比較好走,每走1公里小明會增加1的疲勞度。小道不好走,如果連續走小道,小明的疲勞值會快速增加,連續走s公里小明會增加s2的疲勞度。例如 有5個路口,1號路口到2號路口為小道,2號路口到3號路口為小道,3號路口到4號路...
兩種最短路演算法總結
這裡只總結兩種最短路演算法,第一是 dijkstra,第二是 spfa 這兩種演算法都用了佇列優化,dijkstra是優先佇列,spfa是普通佇列 dijkstra 先介紹第一種,也是用的最多的一種最短路演算法 dijkstra 這種演算法的思想就是先根據給定的起點 s 找到這個點 s 所能連的點,...
最短路徑Dijkstra的兩種實現方法
1 dijkstra單源最短路,鄰接矩陣形式 權值是非負 單源最短路徑,dijkstra演算法,鄰接矩陣形式,複雜度為o n 2 求出源beg到所有點的最短路徑,傳入圖的頂點數,和鄰接矩陣cost 返回個點的最短路徑dist,路徑pre.pre i 記錄beg到i路徑上的父結點,pre beg 1 ...