• hdu1688(dijkstra求最短路和次短路)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688

    题意:第k短路,这里要求的是第1短路(即最短路),第2短路(即次短路),以及路径条数,最后如果最短路和次短路长度差1,则输出两种路径条数之和,否则只输出最短路条数。

    思路:dijkstra变形,注意状态的转移,代码上附了注释,就不多说了..

    代码:

     1 #include <bits/stdc++.h>
     2 #define MAXN 1010
     3 using namespace std;
     4 
     5 vector<pair<int, int> > mp[MAXN]; //***记录图
     6 int dist[MAXN][3]; //***记录源点此时到 i 的距离状态即最短路距离和次短路距离
     7 int cnt[MAXN][3]; //***记录该点作为最短路节点和次短路节点入队次数
     8 int vis[MAXN][3]; //***标记该点的状态即在最短路中,在次短路中,或者未被标记
     9 const int inf=0x3f3f3f3f;
    10 
    11 struct node{ //***重载比较符使优先队列非升序排列
    12     int point, value, tag;//***point记录点, value记录源点到此点的距离,tag标记次点是在最短路中或者在次短路中
    13     friend bool operator< (node a, node b){
    14         return  a.value!=b.value? a.value>b.value : a.point>b.point;
    15     }
    16 };
    17 
    18 int dijkstra_heap_k(int s){
    19     priority_queue<node> q;
    20     memset(dist, 0x3f, sizeof(dist));
    21     memset(vis, false, sizeof(vis));
    22     memset(cnt, 0, sizeof(cnt));
    23 
    24     dist[s][1]=0;
    25     cnt[s][1]=1;
    26     q.push({s, 0, 1});
    27 
    28     while(!q.empty()){
    29         node u=q.top();
    30         int point=u.point;
    31         int tag=u.tag;
    32         q.pop();
    33         if(vis[point][tag]){
    34             continue;
    35         }else{
    36             vis[point][tag]=1;
    37         }
    38         for(int i=0; i<mp[point].size(); i++){
    39             int v=mp[point][i].first;
    40             int cost=mp[point][i].second;
    41 
    42             //***找到比当前最短路更优的路径
    43             if(!vis[v][1]&&dist[v][1]>u.value+cost){
    44                 // 将之前的最短路变为次短路
    45                 if(dist[v][1]!=inf){
    46                     dist[v][2]=dist[v][1];
    47                     cnt[v][2]=cnt[v][1];
    48                     q.push({v, dist[v][2], 2});
    49                 }
    50                 //***更新最短路
    51                 dist[v][1]=u.value+cost;
    52                 cnt[v][1]=cnt[point][tag];
    53                 q.push({v, dist[v][1], 1});
    54             }else if(!vis[v][1]&&dist[v][1]==u.value+cost){
    55                 //***找到一条和当前最短路距离一样的路径,更新最短路数目
    56                 cnt[v][1]+=cnt[point][tag];
    57             }else if(!vis[v][2]&&dist[v][2]>u.value+cost){
    58                 // 比最短路长,比当前次短路短
    59                 dist[v][2]=u.value+cost;
    60                 cnt[v][2]=cnt[point][tag];
    61                 q.push({v, dist[v][2], 2});
    62             }else if(!vis[v][2]&&dist[v][2]==u.value+cost){
    63                 // 和当前次短路一样长
    64                 cnt[v][2]+=cnt[point][tag];
    65             }
    66         }
    67     }
    68 }
    69 
    70 int main(void){
    71     ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    72     int t, n, m;
    73     cin >> t;
    74     while(t--){
    75         cin >> n >> m;
    76         while(m--){
    77             int x, y, z;
    78             cin >> x >> y >> z;
    79             mp[x].push_back({y, z}); //**记录有向图
    80         }
    81         int s, e;
    82         cin >> s >> e;
    83         dijkstra_heap_k(s);
    84         if(dist[e][1]+1==dist[e][2]){
    85             cout << cnt[e][1]+cnt[e][2] << endl;
    86         }else{
    87             cout << cnt[e][1] << endl;
    88         }
    89         for(int i=0; i<MAXN; i++){
    90             mp[i].clear();
    91         }
    92     }
    93     return 0;
    94 }
    View Code
  • 相关阅读:
    自动完成
    自动验证[2]
    自动验证[1]
    PHP算法
    用户请求服务器资源过程
    CURD 操作 [2]
    [转]PHP部分常见算法
    CURD 操作 [1]
    常用正则表达式集锦
    centos 6.4 FTP安装和配置
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/6528406.html
Copyright © 2020-2023  润新知