次短路(兩種方式) 第K短路

2021-09-22 21:33:33 字數 3396 閱讀 1259

有兩種比較簡單實現次短路的思想

題目:poj - 3255

方式一:

tips:其中if(dis2[v] < w) continue; 這句 為true的時候,說明當前節點v 的次短路已經被更新過了 , 如果w比次短路大,說明它肯定是 >= 第三短路 , 也就不用更新了。

#include #include #include #include #include #include #include #include #include #include #include using namespace std;

typedef long long ll;

const int maxn = 1e5 + 7;

const int inf = 1e9 + 7;

int n , m;

int dis1[maxn] , dis2[maxn];

struct node

};vector g[maxn];

void dijkstra());

node q;

int v , w;

while(!que.empty()));

swap(dis1[to_v] , to_w);

}if(dis2[to_v] > to_w && dis1[to_w] < to_w));

}} }

}int main()

); g[v].push_back((node));

} dijkstra();

printf("%d\n",dis2[n]);

}}

方式二:

#include #include #include #include #include #include #include #include #include #include #include using namespace std;

typedef long long ll;

const int maxn = 1e5 + 7;

const int inf = 1e9 + 7;

int n , m , cnt , ans;

int start = 1 , end = n;

int dis1[maxn] , dis2[maxn];

bool vis[maxn];

struct node

};struct edgea[maxn << 1];

vector g[maxn];

void getdis(int op));

else que.push((node));

int v , w;

node q;

while(!que.empty()));

} else if(op && dis2[to_v] > to_w));

}} }

}void dijkstra()

void findcdl()

}int main()

); g[v].push_back((node));

a[++cnt].x = u , a[cnt].y = v , a[cnt].w = w;

a[++cnt].x = v , a[cnt].y = u , a[cnt].w = w;

} dijkstra();

findcdl();

printf("%d\n",ans);

}}

第k短路其實 就是bfs + a*(a*==啟發式搜尋==優化剪枝)

首先求 從 終點 到 每個點的最短路 用 dis[ ] 陣列儲存

然後使用 a* 函式 , f[x] = h[x] + g[x]

題目:poj 2449

具體講解在**內

#include #include #include #include #include #include #include #include #include #include #include using namespace std;

typedef long long ll;

const int maxn = 1e5 + 7;

const int inf = 1e9 + 7;

int n , m , k;

int start , end;

int ans;

//最短路部分

int dis[maxn];

bool vis[maxn];

struct node

};/*

* a* 啟發式搜尋函式 f[x] = h[x] + g[x]

* 變數 hx 表示搜尋到當前點 所用的代價

* 變數 gx 是估價函式 (估價函式要小於等於實際值,否則出錯)

*/struct edge

};/*

* count 記錄第幾次bfs拓展到此點

* 當 count == k 時 不再對此點繼續進行拓展(因為拓展的點必定大於 第k短路)

*/int count[maxn];

vector g[maxn] , g2[maxn];

/* * (因為是有向圖所以反向建圖)

* 求end到每個點的最短路

*/void dijkstra());

dis[end] = 0;

node q;

int v , w;

while(!que.empty()));

}} }}/*

* 第k短路演算法 = a* + bfs

*/void astar());

edge q;

int v , hx , gx;

while(!que.empty())

if(count[v] > k) continue;

int to_v , to_hx , to_gx;

for(int i = 0 ; i < g[v].size() ; i++));

} }while(!que.empty()) que.pop();

return;

}int main()

); g2[v].push_back((node));

} scanf(" %d %d %d",&start , &end , &k);

//此題要求start和end相同的時候 第一短路不是0 ,所以k++

if(start == end) k++;

dijkstra();

astar();

printf("%d\n",ans);

} return 0;

}

第K短路 嚴格第K短路

所謂k短路,就是從s到t的第k短的路,第1短就是最短路。如何求第k短呢?有一種簡單的方法是廣度優先搜尋,記錄t出佇列的次數,當t第k次出佇列時,就是第k短路了。但點數過大時,入佇列的節點過多,時間和空間複雜度都較高。a 是在搜尋中常用的優化,一種啟發式搜尋。簡單的說,它可以用公式表示為f n g n...

第K短路(A 演算法)

對於無向圖 spfa a 演算法 先用spfa求目標結點到各個結點的最短路徑 然後,取g x 為從初始結點到當前結點x的路徑長度,h x 為從x結點到目標結點的最短路徑長度,即h x 取dis x 即可,估價函式f x g x h x 對於有向圖 spfa a 演算法 顯然應將有向邊取反,然後求目標...

第k短路和A

第一次接觸a 感覺好神奇。啟發函式 f x g x h x 比如初始狀態為s,目標狀態為t g x 表示從s到達狀態x所消耗的代價 h x 表示從x到達t所估算的代價 g x 表示s x可能出現的最小代價 h x 表示x t可能出現的最小代價 g x g x h x h x 好吧,上面全是概念。當g...