1. 程式人生 > >wenbao與次短路

wenbao與次短路

vector [] 註意 reat control 相對 nba nod controls

每次更新最短路的時候順便更新次短路 存在d 滿足 dis[i] < d&& d < dis2[i] 更新dis2[i] = d

也可以求兩次最短路(s到t,t到s),然後枚舉每條不包含在最短路上的邊(次短路一定是替換了最短路的一條邊)

既然是次短路,那麽求解k短路的A*算法當然也可以

親測A*相對而言快一點

----------------------------------------

http://poj.org/problem?id=3255

 1 #include <iostream>
 2 #include <queue>
 3
#include <vector> 4 using namespace std; 5 #define pri pair<int, int> 6 const int INF = 1e9; 7 const int maxn = 5009; 8 vector<pri> v[maxn]; 9 int n, r, x, y, z, dis[maxn], dis2[maxn]; 10 void d(){ 11 priority_queue<pri, vector<pri>, greater<pri> > pq;
12 pq.push(pri(0,1)); //pri默認以first排序 13 for(int i = 0; i <= n; ++i) dis[i] = INF, dis2[i] = INF; 14 dis[1] = 0; 15 while(!pq.empty()){ 16 pri b = pq.top(); 17 pq.pop(); 18 int xx = b.second, yy = b.first; 19 if(dis2[xx] < yy) continue; 20 for
(int i = 0; i < v[xx].size(); ++i){ 21 int vv = v[xx][i].first, d = yy + v[xx][i].second; 22 if(dis[vv] > d){ 23 swap(dis[vv], d); //註意是交換,不是賦值,因為dis[vv]可以更新dis2[vv] 24 pq.push(pri(dis[vv], vv)); 25 } 26 if(dis[vv] < d && dis2[vv] > d){ 27 dis2[vv] = d; 28 pq.push(pri(d, vv)); 29 } 30 } 31 } 32 printf("%d\n", dis2[n]); 33 } 34 int main(){ 35 scanf("%d%d", &n, &r); 36 for(int i = 0; i < r; ++i){ 37 scanf("%d%d%d", &x, &y, &z); 38 v[x].push_back(pri(y, z)); 39 v[y].push_back(pri(x, z)); 40 } 41 d(); 42 return 0; 43 }

兩次最短路

 1 #include <iostream>
 2 #include <string.h>
 3 #include <queue>
 4 #include <vector>
 5 using namespace std;
 6 #define INF 1e9;
 7 const int maxn =  5009;
 8 int n, m, from, to, val, d1[maxn], dn[maxn];
 9 bool mark[maxn];
10 vector<int> a[maxn];
11 vector<int> b[maxn];
12 void spfa(int s, int t, int T[]){
13     for(int i = 1; i <= n; ++i) T[i] = INF;
14     T[s] = 0;
15     queue<int> q;
16     q.push(s);
17     while(!q.empty()){
18         int k = q.front();
19         q.pop();
20         mark[k] = false;
21         for(int i = 0; i < a[k].size(); i++)if(T[k] + b[k][i] < T[a[k][i]]) {
22             T[a[k][i]] = T[k] + b[k][i];
23             if(!mark[a[k][i]]){
24                 q.push(a[k][i]);
25                 mark[a[k][i]] = true;
26             }
27         }
28     }
29 }
30 void solve(){
31     int mi = INF;
32     for(int i = 1; i <= n; ++i){
33         for(int j = 0; j < a[i].size(); ++j){
34             int v = a[i][j], d = b[i][j];
35             if(d1[i]+dn[v]+d > d1[n]) mi = min(mi, d1[i]+dn[v]+d);
36         }
37     }
38     printf("%d\n", mi);
39 }
40 int main(){
41     scanf("%d%d", &n, &m);
42     for(int i = 0; i < m; i++) {
43         scanf("%d%d%d", &from, &to, &val);
44         a[from].push_back(to);
45         b[from].push_back(val);
46         a[to].push_back(from);
47         b[to].push_back(val);
48     }
49     spfa(1, n, d1);
50     spfa(n, 1, dn);
51     solve();
52     return 0;
53 }

A*

 1 #include <iostream>
 2 #include <queue>
 3 using namespace std;
 4 
 5 #define INF 1e9;
 6 const int maxn = 200003;
 7 int n, m, to[maxn], w[maxn], pre[maxn], p[5003], index = 1, T[5003];
 8 bool mark[5003];
 9 
10 struct Node{
11     int v, dis;
12     bool operator < (const Node b) const {
13         return dis + T[v] > b.dis + T[b.v];
14     }
15 };
16 
17 void solve(){
18     for(int i = 1; i <= n; ++i) T[i] = INF;
19     T[n] = 0;
20     queue<int> q;
21     q.push(n);
22     while(!q.empty()){
23         int k = q.front();
24         q.pop();
25         mark[k] = false;
26         for(int i = p[k]; i; i = pre[i])if(T[k] + w[i] < T[to[i]]){
27             T[to[i]] = T[k] + w[i];
28             if(!mark[to[i]]){
29                 q.push(to[i]);
30                 mark[to[i]] = true;
31             }
32         }
33     }
34     priority_queue<Node> pq;
35     int cnt = 0;
36     Node a, b;
37     a.v = 1, a.dis = 0;
38     pq.push(a);
39     while(!pq.empty()){
40         a = pq.top(); pq.pop();
41         int v = a.v, dis = a.dis;
42         if(v == n){
43             if(++cnt == 2){
44                 printf("%d\n", dis);
45                 break;
46             }
47         }
48         for(int i = p[v]; i; i = pre[i]){
49             b.v = to[i], b.dis = dis + w[i];
50             pq.push(b);
51         }
52     }
53 }
54 
55 int main(){
56     scanf("%d%d", &n, &m);
57     int x, y, z;
58     for(int i = 0; i < m; ++i){
59         scanf("%d%d%d", &x, &y, &z);
60         to[index] = y, w[index] = z, pre[index] = p[x], p[x] = index++;
61         to[index] = x, w[index] = z, pre[index] = p[y], p[y] = index++;
62     }
63     solve();
64     return 0;
65 }

-----------------------------------

只有不斷學習才能進步!

wenbao與次短路