Flight Discount

题目描述

Your task is to find a minimum-price flight route from Syrjälä to Metsälä. You have one discount coupon, using which you can halve the price of any single flight during the route. However, you can only use the coupon once.

When you use the discount coupon for a flight whose price is x, its price becomes (it is rounded down to an integer).

输入

The first input line has two integers n and m: the number of cities and flight connections. The cities are numbered 1,2,...,n. City 1 is Syrjälä, and city n is Metsälä.

After this there are m lines describing the flights. Each line has three integers a, b, and c: a flight begins at city a, ends at city b, and its price is c. Each flight is unidirectional.

You can assume that it is always possible to get from Syrjälä to Metsälä.

Constraints

2 ≤ n ≤ 105

1 ≤ m ≤ 2*10^5

1 ≤ a,b ≤ n

1 ≤ c ≤ 109

输出

Print one integer: the price of the cheapest route from Syrjälä to Metsälä.

样例输入
复制代码
3 4
1 2 3
2 3 1
1 3 7
2 1 5
样例输出
复制代码
2

**题目大意:**要从1到n,有一张优惠券,可以让在1到n途中的某条路的价格变为一半(向下取整),求从1到n最小的价格

**思路:**dijkstra求最短路。加上优惠券,那就让d再多一个维度,用d[i][j]记录从1到i,j=0:还未使用优惠券时的最小价格,j=1:已经使用过优惠券的最小价格。

注意剪枝(即dijkstra模板中的s数组):加进队列中的这个价格(距离)已经更新过了

cpp 复制代码
if(dist>d[id][flag])
        continue;

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
using tup=tuple<ll,int,int>;//距离,节点编号,是否用券
const int N=100010,M=200010;
int h[N],e[M],ne[M],idx;
ll w[M],d[N][2];//到节点i,0:不使用优惠券,1:使用
void add(int a,int b,int c){
    w[idx]=c,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int n,m;cin>>n>>m;
    memset(h,-1,sizeof(h));
    for (int i=0;i<m;i++){
        int a,b,c;cin>>a>>b>>c;
        add(a,b,c);
    }
    memset(d,0x3f,sizeof(d));
    d[1][0]=0;
    priority_queue<tup,vector<tup>,greater<tup>>pq;
    pq.emplace(0,1,0);
    while(!pq.empty()){
        auto [dist,id,flag]=pq.top();
        pq.pop();
        if(dist>d[id][flag])
        continue;
        for (int i=h[id];i!=-1;i=ne[i]){
            int j=e[i];
            if(flag==0){//还没有使用券
                //不用券
                if(d[j][0]>dist+w[i]){
                    d[j][0]=dist+w[i];
                    pq.emplace(d[j][0],j,0);
                }
                //用券
                if(d[j][1]>dist+w[i]/2){
                    d[j][1]=dist+w[i]/2;
                    pq.emplace(d[j][1],j,1);
                }
            }
            else{//已经使用了券
                if(d[j][1]>dist+w[i]){
                    d[j][1]=dist+w[i];
                    pq.emplace(d[j][1],j,1);
                }
            }
        }
    }
    cout<<min(d[n][0],d[n][1]);
}
相关推荐
罗湖老棍子7 分钟前
【区间DP】括号序列:如何求解最长合法子序列?(POJ 2955)
算法·动态规划·区间dp·区间动态规划·端点匹配型
王德博客11 分钟前
【实现常见排序算法】直接插入排序的算法思想
数据结构·算法·排序算法
m0_5648768412 分钟前
分布式训练DP与DDP
人工智能·深度学习·算法
纤纡.13 分钟前
逻辑回归实战进阶:交叉验证与采样技术破解数据痛点(一)
算法·机器学习·逻辑回归
重生之后端学习16 分钟前
146. LRU 缓存
java·数据结构·算法·leetcode·职场和发展
程曦曦18 分钟前
原地删除有序数组重复项:双指针法的艺术与实现
数据结构·算法·leetcode
你怎么知道我是队长19 分钟前
C语言---排序算法6---递归归并排序法
c语言·算法·排序算法
智驱力人工智能31 分钟前
景区节假日车流实时预警平台 从拥堵治理到体验升级的工程实践 车流量检测 城市路口车流量信号优化方案 学校周边车流量安全分析方案
人工智能·opencv·算法·安全·yolo·边缘计算
MicroTech202533 分钟前
微算法科技(NASDAQ :MLGO)抗量子攻击区块链共识机制:通过量子纠缠态优化节点验证流程,降低计算复杂度
科技·算法·区块链
pp起床34 分钟前
贪心算法 | part01
算法·贪心算法