【codevs1269】匈牙利游戏

Welcome to the Hungary Games!

题目描述 Description

欢迎来到匈牙利游戏!布达佩斯(匈牙利首都)的街道形成了一个弯曲的单向网络。
你被强制要求参加一个赛跑作为一个TV秀的一部分节目,比赛中你需要穿越这些街道,从s开始,到t结束。
很自然的,你想要尽快的完成比赛,因为你的比赛完成的越好,你就能得到更多的商业促销合同。
但是,有一个需要了解的是,如果有人过于聪明找到从s到t的最短路线,那么他就被扔到国家极品人类保护系统中作为一个国家宝藏收藏起来。你显然要避免这种事情的发生,但是也想越快越好。写一个程序来计算一个从s到t的严格次短路线吧。
有的时候,严格次短路线可能访问某些节点不止一次。样例2是一个例子。

输入描述 Input Description

第一行包含两个整数N和M,N代表布达佩斯的节点个数,M代表边的个数。节点编号从1到N。1代表出发点s,N代表终点t。接下来的M行每行三个整数A B L,代表有一条从A到B的长度为L的单向同路。你可以认为A不等于B,也不会有重复的(A,B)对。

输出描述 Output Description

输出从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

这道题叫次短路……
和最短路类似,但略有不同
主要就是开第二个距离数组dist2(也就是代码中的cdl(次短路))
用来存放次短路长度
当然也可以用结构体储存辣
下面是代码~_~

#include<queue>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
long long tot,dist1[200010],cdl[200010],head[200010],Ts,Te,T,C;
bool passby[200010];
struct Edge
{
    int next,to,dist;
}edge[900010];
void add(int from,int to,int dd)//dd=距离;
{
    edge[++tot].to=to;//加终点 
    edge[tot].dist=dd;//加距离 
    edge[tot].next=head[from];//更新上条路 
    head[from]=tot;//更新这条路 
}
queue<int> q;
void spfa(int s)
{
    dist1[s]/*=cdl[s]*/=0;
    passby[s]=1;
    q.push(s);
    for(;!q.empty();)
    {
        int x=q.front();
        passby[x]=0;
        q.pop();
        for(int i=head[x];i;i=edge[i].next)
        {
            Edge e=edge[i];
            if(dist1[e.to]>dist1[x]+e.dist)
            {
                cdl[e.to]=dist1[e.to];
                dist1[e.to]=dist1[x]+e.dist;
                if(!passby[e.to])
                {
                    passby[e.to]=1;
                    q.push(e.to);
                }
            }
            else if(cdl[e.to]>dist1[x]+e.dist&&dist1[e.to]<dist1[x]+e.dist)//注意&&后的东西 
            {
                cdl[e.to]=dist1[x]+e.dist;
                if(!passby[e.to])
                {
                    passby[e.to]=1;
                    q.push(e.to);
                }
            }
            else if(cdl[e.to]>cdl[x]+e.dist)
            {
                cdl[e.to]=cdl[x]+e.dist;
                if(!passby[e.to])
                {
                    passby[e.to]=1;
                    q.push(e.to);
                }
            }
        }
    }
}
int main()
{
    cin>>T>>C;
    for(int i=0;i<=C+5;i++)dist1[i]=cdl[i]=0x7ffffffffffffff;
    for(int i=1;i<=C;i++)
    {
        int Rs,Re,Ci;
        cin>>Rs>>Re>>Ci;
        add(Rs,Re,Ci);
    }
    spfa(1);
    if(cdl[T]!=0x7ffffffffffffff)
        cout<<cdl[T];
    else
        cout<<"-1" ;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值