SPFA演算法 例題 問題 A 黑暗城堡

2021-09-24 05:49:38 字數 1692 閱讀 1324

演算法思想:

1) 三角形中的性質:同一三角形內兩邊之和大於第三邊。

2)由上面那一條性質,我們可以想出乙個方法來更新源點到其他點的最短的路徑:用中間節點k鬆弛u->k->v,來更新u->v的最短路徑(思想和floy演算法相似),也就是說,我們實際上每次都是在判斷這條路徑符不符合三角形不等式dis[v]v],若不符合,我們就將原先的路徑鬆弛為現在的路徑,使得現在的路徑滿足三角形不等式。

3)但是為什麼鬆弛後要將終點入隊呢?spfa的過程是bfs,它是不停擴充套件節點的。而當我們更新了這一條路徑,那麼可能會出現基於這一條路徑的新路,我們需要判斷原路與新路是否滿足三角形不等式。即:有了新的最短路,就用它再去更新與他相連的點的最短路。

實現及細節

1)用visit[ ]陣列來維護已經入隊的頂點;並注意:出隊時消除標記

2)用佇列來維護鬆弛過的頂點

3)用鏈式前向星存圖(連線?)

4)dis[ ]陣列要初始化為inf;

上**:

struct edgee[

10000];

bool visit[

10000];

dis[

10000];

int head[

1005]=

;int cnt;

void

init()

inline

void

add(

int u,

int v,

int w)

///無向邊,所以加兩次,若是有向邊只需要加一次;

void

spfa()

}}}}

例題 黑暗城堡

#include

#include

#include

using namespace std;

typedef

long

long ll;

const

int mod=

2147483647

;bool visit[

1005]=

;ll dis[

1005

],num[

1005]=

;///距離陣列,num[i]代表起點i符合條件的個數

void

init()

struct edge

e[1000005];

///邊

int head[

1005]=

;int cnt;

inline

void

add(

int u,

int v,

int w)

///無向邊,所以加兩次

void

spfa()

}}}}

intmain()

spfa()

;for

(int i=

1;i<=n;i++

)///遍歷所有頂點

}for

(int i=

2;i<=n;i++

) ans*

=num[i]

,ans%

=mod;

///排列組合的乘法原理

cout

}

Dijkstra演算法 例題

dijkstra演算法 從起點到終點求最短路 使用要求權值為正 1 求短路i 題目 點數 500 邊數 1e5 include include include using namespace std const int n 510,m 1e5 10 時間複雜度o n m int n,m 鄰接矩陣 i...

模擬演算法例題

一 火柴棒 題目描述 給你n根火柴棍,你可以拼出多少個形如 a b c 的等式?等式中的a b c是用火柴棍拼出的整數 若該數非零,則最高位不能是0 用火柴棍拼數字0 9的拼法如圖所示 注意 1 加號與等號各自需要兩根火柴棍 2 如果a b,則a b c與b a c視為不同的等式 a b c 0 3...

manacher演算法 例題

簡單而有通俗的講解,講的太好了 證明對於一些我的理解,我會以 注釋的形式寫在 裡,我不懶 char str maxn char temp maxn 1 10 擴充套件後的字串 int len maxn 1 10 擴充套件後字串第i個位置回文串從中間到第有邊界的長度 相當於 回文子串長度 2 1 在用...