(最短路+A*搜索)POJ 2449 - Remmarguts' Date

題意:node

給一個DAG,要求s到t的第K短路,很經典的問題。ios


 

分析:函數

咱們能夠看到k<=1000,這個值不是很大,我能夠想到直接bfs走遍全部狀況,最多也就有1000中狀況,可是1000個點顯然會M。spa

既然是要求k短路,也就是說最終計算出來的到達t的花費必然是遞增的,也就是說咱們在搜索的時候確定要用到優先隊列。code

這時應該很明顯了,必然須要A*搜索,可是A*的預估函數依然是個問題,我想了好久沒有想到,後來偶然在一本書上發現了這題。blog

書上的處理是用dijsktra預處理每點到t的最短路,就是每一個狀態到達目標的預估值。隊列

恍然大悟。string

可是怎麼求每一個點到t的最短路的,咱們知道dijsktra的中間變量dist計算的是s到每一個頂點的最短路,咱們只須要把原圖構建一個反向圖,it

計算t到每一個點的最短路,就是原圖每一個點到t的最短路,這時候再進行普通的A*就好了。io

然而本題一堆坑。

一、你須要再A*的時候判連通,否則將死循環

二、須要特殊處理從本身走到本身的狀況,初始的0顯然不算在k短路內。


 

代碼:

  1 #include <set>
  2 #include <map>
  3 #include <list>
  4 #include <cmath>
  5 #include <queue>
  6 #include <stack>
  7 #include <vector>
  8 #include <bitset>
  9 #include <string>
 10 #include <cctype>
 11 #include <cstdio>
 12 #include <cstring>
 13 #include <cstdlib>
 14 #include <iostream>
 15 #include <algorithm>
 16 // #include <unordered_map>
 17 
 18 using namespace std;
 19 
 20 typedef long long ll;
 21 typedef unsigned long long ull;
 22 typedef pair<int, int> pii;
 23 typedef pair<ull, ull> puu;
 24 
 25 #define inf (0x3f3f3f3f)
 26 #define lnf (0x3f3f3f3f3f3f3f3f)
 27 #define eps (1e-9)
 28 #define fi first
 29 #define se second
 30 
 31 bool sgn(double a, string select, double b) {
 32     if(select == "==")return fabs(a - b) < eps;
 33     if(select == "!=")return fabs(a - b) > eps;
 34     if(select == "<")return a - b < -eps;
 35     if(select == "<=")return a - b < eps;
 36     if(select == ">")return a - b > eps;
 37     if(select == ">=")return a - b > -eps;
 38 }
 39 
 40 
 41 //--------------------------
 42 
 43 const ll mod = 1000000007;
 44 const int maxn = 1010;
 45 
 46 //use to bfs
 47 struct Node {
 48     int v, c;
 49     Node(int _v = 0, int _c = 0) {
 50         v = _v, c = _c;
 51     }
 52     bool operator<(const Node &a)const {
 53         return c > a.c;
 54     }
 55 };
 56 
 57 //first is 'v' , second is 'cost'
 58 vector<pii> edge[maxn];
 59 vector<pii> zedge[maxn];
 60 bool vis[maxn];
 61 int dist[maxn];
 62 
 63 void addedge(int u, int v, int w) {
 64     edge[v].push_back(make_pair(u, w));
 65     zedge[u].push_back(make_pair(v, w));
 66 }
 67 
 68 // id from 1
 69 void dijkstra_heap(int n, int start) {
 70     memset(vis, 0, sizeof(vis));
 71     for(int i = 1; i <= n; i++) dist[i] = inf;
 72     priority_queue<Node> que;
 73     while(!que.empty())que.pop();
 74     dist[start] = 0;
 75     que.push(Node(start, 0));
 76     Node tmp;
 77     while(!que.empty()) {
 78         tmp = que.top();
 79         que.pop();
 80         int u = tmp.v;
 81         if(vis[u])continue;
 82         vis[u] = true;
 83         for(int i = 0; i < edge[u].size(); i++) {
 84             int v = edge[u][i].fi;
 85             int cost = edge[u][i].se;
 86             if(!vis[v] && dist[v] > dist[u] + cost) {
 87                 dist[v] = dist[u] + cost;
 88                 que.push(Node(v, dist[v]));
 89             }
 90         }
 91     }
 92 }
 93 
 94 struct anode {
 95     int v;
 96     int f, g, h;
 97     anode(int _v = 0, int _f = 0, int _g = 0, int _h = 0) {
 98         v = _v, f = _f, g = _g, h = _h;
 99     }
100     bool operator<(const anode &a)const {
101         return f > a.f;
102     }
103 };
104 
105 int n, m;
106 int s, t, k;
107 
108 bool Astar(int start) {
109     if(s == t) {
110         k++;
111     }
112     if(dist[start] == inf) {
113         return false;
114     }
115     priority_queue<anode> que;
116     while(!que.empty())que.pop();
117     int num = 0;
118     que.push(anode(start, dist[start], 0, dist[start]));
119     while(!que.empty()) {
120         anode tmp = que.top();
121         que.pop();
122         if(tmp.v == t) {
123             num++;
124             // printf("%d\n", tmp.g );
125         }
126         if(num >= k) {
127             printf("%d\n", tmp.g );
128             return true;
129         }
130         int u = tmp.v;
131         for(int i = 0; i < zedge[u].size(); i++) {
132             int v = zedge[u][i].fi;
133             int cost = zedge[u][i].se;
134             int g = tmp.g + cost;
135             int h = dist[v];
136             int f = g + h;
137             que.push(anode(v, f, g, h));
138         }
139     }
140     return false;
141 }
142 
143 
144 void solve() {
145     while(~scanf("%d%d", &n, &m)) {
146         for(int i = 1; i <= n; i++) {
147             edge[i].clear();
148             zedge[i].clear();
149         }
150         int u, v, w;
151         for(int i = 0; i < m; i++) {
152             scanf("%d%d%d", &u, &v, &w);
153             addedge(u, v, w);
154         }
155         scanf("%d%d%d", &s, &t, &k);
156         dijkstra_heap(n, t);
157         if(!Astar(s)) {
158             puts("-1");
159         }
160     }
161 }
162 
163 int main() {
164 
165 #ifndef ONLINE_JUDGE
166     freopen("1.in", "r", stdin);
167     freopen("1.out", "w", stdout);
168 #endif
169     // iostream::sync_with_stdio(false);
170     solve();
171     return 0;
172 }
相關文章
相關標籤/搜索