codevs 1269 匈牙利游戏(次短路)

题目描述 Description
Welcome to the Hungary Games! The streets of Budapest form a twisted network of one-way streets.
欢迎来到匈牙利游戏!布达佩斯(匈牙利首都)的街道形成了一个弯曲的单向网络。
You have been forced to join a race as part of a “Reality TV” show where you race through these streets, starting at the Sz´echenyi thermal bath (s for short) and ending at the Tomb of G¨ ul Baba (t for short).
你被强制要求参加一个赛跑作为一个TV秀的一部分节目,比赛中你需要穿越这些街道,从s开始,到t结束。
Naturally, you want to complete the race as quickly as possible, because you will get more promo- tional contracts the better you perform.
很自然的,你想要尽快的完成比赛,因为你的比赛完成的越好,你就能得到更多的商业促销合同。
However, there is a catch: any person who is smart enough to take a shortest s-t route will be thrown into the P´alv¨olgyi cave system and kept as a national treasure. You would like to avoid this fate, but still be as fast as possible. Write a program that computes a strictly-second-shortest s-t route.
但是,有一个需要了解的是,如果有人过于聪明找到从s到t的最短路线,那么他就被扔到国家极品人类保护系统中作为一个国家宝藏收藏起来。你显然要避免这种事情的发生,但是也想越快越好。写一个程序来计算一个从s到t的严格次短路线吧。
Sometimes the strictly-second-shortest route visits some nodes more than once; see Sample Input 2 for an example.
有的时候,严格次短路线可能访问某些节点不止一次。样例2是一个例子。

输入描述 Input Description
The first line will have the format N M, where N is the number of nodes in Budapest and M is the number of edges. The nodes are 1,2,…,N; node 1 represents s; node N represents t. Then there are M lines of the form A B L, indicating a one-way street from A to B of length L. You can assume that A != B on these lines, and that the ordered pairs (A,B) are distinct.
第一行包含两个整数N和M,N代表布达佩斯的节点个数,M代表边的个数。节点编号从1到N。1代表出发点s,N代表终点t。接下来的M行每行三个整数A B L,代表有一条从A到B的长度为L的单向同路。你可以认为A不等于B,也不会有重复的(A,B)对。

输出描述 Output Description
Output the length of a strictly-second-shortest route from s to t. If there are less than two possible lengths for routes from s to t, output −1.
输出从s到t的严格次短路的长度。如果从s到t的路少于2条,输出-1。

样例输入 Sample Input
样例输入1:
4 6
1 2 5
1 3 5
2 3 1
2 4 5
3 4 5
1 4 13

样例输入2:
2 2
1 2 1
2 1 1

样例输出 Sample Output
样例输出1:
11

样例输出2:
3

数据范围及提示 Data Size & Hint
对于样例1:
There are two shortest routes of length 10 (1 → 2 → 4,1 → 3 → 4) and the strictly-second- shortest route is 1 → 2 → 3 → 4 with length 11.

对于样例2:
The shortest route is 1 → 2 of length 1, and the strictly-second route is 1 → 2 → 1 → 2 of length 3.

题解:题目的大意是给你一张图(我不要╭(╯^╰)╮),求这张图的严格次短路。
首先,如果最短路能更新最短路,就让它更新最短路,然后让以前的最短路去更新次短路,如果最短路不能更新最短路,但是能更新次短路,就让它更新次短路(注意:因为求的是严格次短路,所以要判断一下这里的最短路不能等于当前的最短路),然后如果次短路能更新次短路,就让它更新次短路。所以我们只要跑一遍spfa就能找到严格次短路233

代码如下

#include<queue> 
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int MAXV=110000;
const int MAXE=610000;
int first[MAXV],nxt[MAXE<<1];
int d[MAXV],nd[MAXV];//d数组记录最短路,nd数组记录次短路 
bool used[MAXV];
int n,m,tot;
struct edge
{
    int from,to,cost;
}es[MAXE<<1];
void init()
{
    memset(first,-1,sizeof(first));
    memset(nd,63,sizeof(nd));
    memset(d,63,sizeof(d));
    tot=0;
}
void build(int f,int t,int d)
{
    es[++tot]=(edge){f,t,d};
    nxt[tot]=first[f];
    first[f]=tot;
}
queue<int> Q;
void spfa()
{
    d[1]=0;
    Q.push(1);
    used[1]=1;
    while(!Q.empty())
    {
        int u=Q.front();
        Q.pop();
        used[u]=0;
        for(int i=first[u];i!=-1;i=nxt[i])
        {
            int v=es[i].to;
            if(d[v]>d[u]+es[i].cost)//如果最短路能更新最短路 
            {
                nd[v]=d[v];//最短路更新次短路 
                d[v]=d[u]+es[i].cost;
                if(!used[v])
                {
                    Q.push(v);
                    used[v]=1;
                }
            }
            else if(nd[v]>d[u]+es[i].cost&&d[u]+es[i].cost!=d[v])
            {//最短路不能更新最短路,但是能更新次短路 
                nd[v]=d[u]+es[i].cost;
                if(!used[v])
                {
                    Q.push(v);
                    used[v]=1;
                }
            }
            else if(nd[v]>nd[u]+es[i].cost)
            {//次短路能更新次短路 
                nd[v]=nd[u]+es[i].cost;
                if(!used[v])
                {
                    Q.push(v);
                    used[v]=1;
                }
            }
        }
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    init();
    for(int i=1;i<=m;i++)
    {
        int a,b,l;
        scanf("%d%d%d",&a,&b,&l);
        build(a,b,l);
    }
    spfa();
    if(nd[n]!=1061109567) printf("%d",nd[n]);
    else printf("-1\n");//不要忘了没有次短路要输出-1 
    return 0;
}
  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值