• bzoj1726:[Usaco2006 Nov]Roadblocks 次短路


    Description

    贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友。贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路。 贝茜所在的乡村有R(1<=R<=100,000)条双向道路,每条路都联结了所有的N(1<=N<=5000)个农场中的某两个。贝茜居住在农场1,她的朋友们居住在农场N(即贝茜每次旅行的目的地)。 贝茜选择的第二短的路径中,可以包含任何一条在最短路中出现的道路,并且,一条路可以重复走多次。当然咯,第二短路的长度必须严格大于最短路(可能有多条)的长度,但它的长度必须不大于所有除最短路外的路径的长度。

    Input

    * 第1行: 两个整数,N和R,用空格隔开
    * 第2..R+1行: 每行包含三个用空格隔开的整数A、B和D,表示存在一条长度为 D(1 <= D <= 5000)的路连接农场A和农场B

    Output

    * 第1行: 输出一个整数,即从农场1到农场N的第二短路的长度

    Sample Input

    4 4
    1 2 100
    2 4 200
    2 3 250
    3 4 100

    Sample Output

    450
    //最短路:1 -> 2 -> 4 (长度为100+200=300)
    第二短路:1 -> 2 -> 3 -> 4 (长度为100+250+100=450)

    这是道好题啊,相信大家第一秒看到觉得简单,稍加思考就懵逼了吧,不然也不会看到我这句话。

    好了,说正经的:

    这道题显然是spfa(虽然范围并不大,但是还是spfa)

    其实和普通的spfa没什么两样,就是开一个存次短路的数组,然后在判断最短路径不是更优的时候判断一遍次短路径是否更优,如果是的,替换就行了

    这里有一个点不得不说:在找到更优的最短路径的时候,原有的最短路径肯定变成了当前的次短路径(因为我们的目的就是在原有的最短路径上替换一条边,再使替换的这条边最短),所以我们每更新一次最短路,就要连次短路一起更新,精髓好好体会吧。

    看代码(就多了一个数组和一个if):

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 int sum,n,m,q[5001],last[5001];
     6 bool used[5001];
     7 long long dis[5001],dis2[5001];
     8 struct data
     9 {
    10     int a,next,v;
    11 }f[200001];
    12 void ins(int u,int v,int w)
    13 {
    14     sum++;
    15     f[sum].a=v;
    16     f[sum].v=w;
    17     f[sum].next=last[u];
    18     last[u]=sum;
    19 }
    20 int main()
    21 {
    22     int t=0,w=1,now,i,u,v,x;
    23     scanf("%d%d",&n,&m);
    24     for(int i=1;i<=n;i++)dis[i]=dis2[i]=1e15;
    25     for(int i=1;i<=m;i++)
    26         scanf("%d%d%d",&u,&v,&x),ins(u,v,x),ins(v,u,x);
    27     q[0]=1,used[1]=1,dis[1]=0;
    28     while(t!=w)
    29     {
    30         now=q[t++];
    31         if(t==n)t=0;
    32         for(i=last[now];i;i=f[i].next)
    33         {
    34             if(dis[now]+f[i].v<dis[f[i].a])
    35             {
    36                 dis2[f[i].a]=dis[f[i].a];//在找到更优的最短路径的时候,原有的最短路径肯定变成了当前的次短路径
    37                 dis[f[i].a]=dis[now]+f[i].v;
    38                 if(!used[f[i].a])
    39                 {
    40                     used[f[i].a]=1;
    41                     q[w++]=f[i].a;
    42                     if(w==n)w=0;
    43                 }
    44             }
    45             else if(dis[now]+f[i].v<dis2[f[i].a]&&dis[now]+f[i].v>dis[f[i].a])
    46             {
    47                 dis2[f[i].a]=dis[now]+f[i].v;
    48                 if(!used[f[i].a])
    49                 {
    50                     used[f[i].a]=1;
    51                     q[w++]=f[i].a;
    52                     if(w==n)w=0;
    53                 }
    54             }
    55             if(dis2[now]+f[i].v<dis2[f[i].a])
    56             {
    57                 dis2[f[i].a]=dis2[now]+f[i].v;
    58                 if(!used[f[i].a])
    59                 {
    60                     used[f[i].a]=1;
    61                     q[w++]=f[i].a;
    62                     if(w==n)w=0;
    63                 }
    64             }
    65         }
    66         used[now]=0;
    67     }
    68     if(dis2[n]!=1e15)printf("%d",dis2[n]);
    69     else printf("-1");
    70 }
  • 相关阅读:
    Cesium中的坐标系及转换
    Cesium Workshop
    window.postMessage 跨窗口,跨iframe javascript 通信
    VUE课程参考---7、跑马灯效果
    VUE课程---9、事件绑定v-on
    VUE课程---8、属性绑定v-bind
    VUE课程---7、解决插值表达式闪烁问题
    小谈chrome调试命令:console.log的使用
    Hadoop平台配置总结
    hadoop 关闭进程时报错no 进程 to stop
  • 原文地址:https://www.cnblogs.com/lcxer/p/9441656.html
Copyright © 2020-2023  润新知