日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

poj 2449

發布時間:2023/11/30 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 poj 2449 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自http://blog.csdn.net/sdj222555/article/details/7690081

?

題目大意就是給出一個圖,然后給出一個起點個一個終點,求這兩點間的第K短路。

本題中是可以走重復的路的,所以如果一張圖中有一個環的話,無論求第幾短路都是存在的。

?

網上大部分的方法都是用A* + 最短路的方法做的。 ?

對于A* ,估價函數 = 當前值+當前位置到終點的距離,即 F(p)=g(p)+h(p),每次擴展估價函數值中最小的一個。對于k短路來說,g(p)為當前從s到p所走的長度,h(p)為從p到 t 的最短路的長度,則F(p)的意義就是從s按照當前路徑走到 p 后要走到終點 t 一共至少要走多遠。也就是說我們每次的擴展都是有方向的擴展,這樣就可以提高求解速度和降低擴展的狀態數目。為了加速計算,h(p)需要從A*搜索之前進行預處理,只要將原圖的所有邊反向,再從終點 t 做一次單源最短路徑就可以得到每個點的h(p)了。

在下面這個代碼中

A結構體中,v代表的是當前走到的點,f和g分別為f函數和g函數的值,每次優先搜的是f函數較小的。這樣就能保證搜索出來的一定是第K小短路,并且避免了一定的不必要計算。

?

1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cstdio> 5 #include <queue> 6 #define MAXN 1005 7 #define MAXM 500005 8 #define INF 1000000000 9 using namespace std; 10 struct node 11 { 12 int v, w, next; 13 }edge[MAXM], revedge[MAXM]; 14 struct A 15 { 16 int f, g, v; 17 bool operator <(const A a)const { 18 if (a.f == f) return a.g < g; 19 return a.f < f; 20 } 21 }; 22 int e, vis[MAXN], d[MAXN], q[MAXM * 5]; 23 int head[MAXN], revhead[MAXN]; 24 int n, m, s, t, k; 25 void init() 26 { 27 e = 0; 28 memset(head, -1, sizeof(head)); 29 memset(revhead, -1, sizeof(revhead)); 30 } 31 void insert(int x, int y, int w) 32 { 33 edge[e].v = y; 34 edge[e].w = w; 35 edge[e].next = head[x]; 36 head[x] = e; 37 revedge[e].v = x; 38 revedge[e].w = w; 39 revedge[e].next = revhead[y]; 40 revhead[y] = e++; 41 } 42 void spfa(int src) 43 { 44 for (int i = 1; i <= n; i++) d[i] = INF; 45 memset(vis, 0, sizeof(vis)); 46 vis[src] = 0; 47 int h = 0, t = 1; 48 q[0] = src; 49 d[src] = 0; 50 while (h < t) 51 { 52 int u = q[h++]; 53 vis[u] = 0; 54 for (int i = revhead[u]; i != -1; i = revedge[i].next) 55 { 56 int v = revedge[i].v; 57 int w = revedge[i].w; 58 if (d[v] > d[u] + w) 59 { 60 d[v] = d[u] + w; 61 if (!vis[v]) 62 { 63 q[t++] = v; 64 vis[v] = 1; 65 } 66 } 67 } 68 } 69 } 70 int Astar(int src, int des) 71 { 72 int cnt = 0; 73 priority_queue<A>Q; 74 if (src == des) k++; 75 if (d[src] == INF) return -1; 76 A t, tt; 77 t.v = src, t.g = 0, t.f = t.g + d[src]; 78 Q.push(t); 79 while (!Q.empty()) 80 { 81 tt = Q.top(); 82 Q.pop(); 83 if (tt.v == des) 84 { 85 cnt++; 86 if (cnt == k) return tt.g; 87 } 88 for (int i = head[tt.v]; i != -1; i = edge[i].next) 89 { 90 t.v = edge[i].v; 91 t.g = tt.g + edge[i].w; 92 t.f = t.g + d[t.v]; 93 Q.push(t); 94 } 95 } 96 return -1; 97 } 98 int main() 99 { 100 int x, y, w; 101 while (scanf("%d%d", &n, &m) != EOF) 102 { 103 init(); 104 for (int i = 1; i <= m; i++) 105 { 106 scanf("%d%d%d", &x, &y, &w); 107 insert(x, y, w); 108 } 109 scanf("%d%d%d", &s, &t, &k); 110 spfa(t); 111 printf("%d\n", Astar(s, t)); 112 } 113 return 0; 114 }

?

轉載于:https://www.cnblogs.com/usedrosee/p/4262396.html

總結

以上是生活随笔為你收集整理的poj 2449的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。