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再多一个维度,用dij记录从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]);
}
相关推荐
政企项目老覃8 小时前
大模型幻觉治理与自动评测:金融风控场景的落地实践
人工智能·算法·机器学习
淡海水8 小时前
08-03-不可变-ImmutableDictionary-TKey-TValue-与ImmutableHashSet-T-持久化哈希树
数据结构·算法·c#·哈希算法·dictionary·immutable
hansang_IR8 小时前
【题解】[APIO2023] 赛博乐园 / cyberland
c++·算法·图论
洛阳纸贵8 小时前
MATLAB-matlab基础知识
学习·算法·matlab
落羽的落羽8 小时前
【AI】快速理解AI应用的相关名词概念
linux·c++·人工智能·python·计算机网络·算法
Nil2089 小时前
leetcode 17电话号码的字母组合
算法·leetcode·职场和发展
203号居民10 小时前
LeetCode hot 100 — 25. K 个一组翻转链表
算法·leetcode·链表
ocean210311 小时前
2025-2026年AI算法与模型研发面试高频知识点洞察
人工智能·算法·面试
Nil20811 小时前
leetcode 78子集
数据结构·算法·leetcode