zoukankan      html  css  js  c++  java
  • wenbao与次短路

    每次更新最短路的时候顺便更新次短路 存在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
    ", 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
    ", 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
    ", 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 }

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

    只有不断学习才能进步!

  • 相关阅读:
    redis的基本操作
    python对txt的读写
    python random的练习
    python继承的练习
    python类和实例
    VS2019 自动代码补全功能
    GIT 删除操作
    vue-router 注意事项
    Vue中axios访问 后端跨域问题
    Vue2.0 搭配 axios
  • 原文地址:https://www.cnblogs.com/wenbao/p/7436546.html
Copyright © 2011-2022 走看看