zoukankan      html  css  js  c++  java
  • POJ 3463 Sightseeing

    题目链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=110697#problem/A

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

    给定一个有向正权图和起点终点 求最短路以及比最短路长$1$的路径的个数(允许一条边走两次)

    我们知道 $dijkstra$ 是基于一种贪心的思想 当某点成为当前所有未被使用的点中距离最近的点时

    它就可以开始用来更新其他的点 并且它的距离是不可能再改变的

    如果要求路径数的话 到这个点的最短路径的数量显然也是不会再变的

    因此记录最短路径数量就有点像$DAG$上做的$dp$

    至于求次短路 我们可以把每个点的次短路单独抽出来作为新的$n$个点(不过仍然受原来的求最短路的点影响)

    这样在新的图上跑最短路就可以一次同时得到最短路和次短路了

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cmath>
     4 #include <algorithm>
     5 using namespace std;
     6 const int N = 1010, E = 10010;
     7 int firste[N], nexte[E], v[E], w[E];
     8 int dist[N << 1], cnt[N << 1];
     9 bool used[N << 1];
    10 int t, n, m, e;
    11 void build(int x,int y, int z)
    12 {
    13     nexte[++e] = firste[x];
    14     firste[x] = e;
    15     v[e] = y;
    16     w[e] = z;
    17 }
    18 void dijkstra(int s)
    19 {
    20     memset(dist, 0x3f, sizeof dist);
    21     memset(cnt, 0, sizeof cnt);
    22     memset(used, 0, sizeof used);
    23     dist[s] = 0;
    24     cnt[s] = 1;
    25     int u = s, tu, mdist;
    26     for(int tt = 1; tt < n * 2; ++tt)
    27     {
    28         mdist = 1e9 + 10;
    29         used[u] = 1;
    30         if(u <= n)
    31             for(int p = firste[u]; p; p = nexte[p])
    32             {
    33                 if(dist[v[p]] > dist[u] + w[p])
    34                 {
    35                     dist[v[p] + n] = dist[v[p]];
    36                     cnt[v[p] + n] = cnt[v[p]];
    37                     dist[v[p]] = dist[u] + w[p];
    38                     cnt[v[p]] = cnt[u];
    39                 }
    40                 else if(dist[v[p]] == dist[u] + w[p])
    41                     cnt[v[p]] += cnt[u];
    42                 else if(dist[v[p] + n] > dist[u] + w[p])
    43                 {
    44                     dist[v[p] + n] = dist[u] + w[p];
    45                     cnt[v[p] + n] = cnt[u];
    46                 }
    47                 else if(dist[v[p] + n] == dist[u] + w[p])
    48                     cnt[v[p] + n] += cnt[u];
    49             }
    50         else
    51             for(int p = firste[u - n]; p; p = nexte[p])
    52             {
    53                 if(dist[v[p] + n] > dist[u] + w[p])
    54                 {
    55                     dist[v[p] + n] = dist[u] + w[p];
    56                     cnt[v[p] + n] = cnt[u];
    57                 }
    58                 else if(dist[v[p] + n] == dist[u] + w[p])
    59                     cnt[v[p] + n] += cnt[u];
    60             }
    61         for(int i = 1; i <= n * 2; ++i)
    62             if(!used[i] && dist[i] < mdist)
    63             {
    64                 mdist = dist[i];
    65                 tu = i;
    66             }
    67         u = tu;
    68     }
    69 }
    70 int main()
    71 {
    72     scanf("%d", &t);
    73     while(t--)
    74     {
    75         e = 1;
    76         memset(firste, 0, sizeof firste);
    77         scanf("%d%d", &n, &m);
    78         int x, y, z;
    79         while(m--)
    80         {
    81             scanf("%d%d%d", &x, &y, &z);
    82             build(x, y, z);
    83         }
    84         int s, f;
    85         scanf("%d%d", &s, &f);
    86         dijkstra(s);
    87         printf("%d
    ", cnt[f] + cnt[f + n] * (dist[f + n] == dist[f] + 1));
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    防雪崩利器:熔断器 Hystrix 的原理与使用
    SpringBoot返回结果为null或空值不显示处理方法
    Tomca原理分析之责任链
    TOMCAT原理详解及请求过程
    RocketMQ支持事务消息机制
    ubuntu 安装rocketmq
    Monkey安装与配置教程
    Monkey通过安装包获取包名
    git使用笔记
    Linux解压命令
  • 原文地址:https://www.cnblogs.com/sagitta/p/5327648.html
Copyright © 2011-2022 走看看