首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >航班Flight(SPFA+dp)- HDU 3499

航班Flight(SPFA+dp)- HDU 3499

作者头像
ACM算法日常
发布于 2018-08-07 09:02:44
发布于 2018-08-07 09:02:44
41100
代码可运行
举报
文章被收录于专栏:ACM算法日常ACM算法日常
运行总次数:0
代码可运行

Recently, Shua Shua had a big quarrel with his GF. He is so upset that he decides to take a trip to some other city to avoid meeting her. He will travel only by air and he can go to any city if there exists a flight and it can help him reduce the total cost to the destination. There's a problem here: Shua Shua has a special credit card which can reduce half the price of a ticket ( i.e. 100 becomes 50, 99 becomes 49. The original and reduced price are both integers. ). But he can only use it once. He has no idea which flight he should choose to use the card to make the total cost least. Can you help him?

Input

There are no more than 10 test cases. Subsequent test cases are separated by a blank line. The first line of each test case contains two integers N and M ( 2 <= N <= 100,000 0 <= M <= 500,000 ), representing the number of cities and flights. Each of the following M lines contains "X Y D" representing a flight from city X to city Y with ticket price D ( 1 <= D <= 100,000 ). Notice that not all of the cities will appear in the list! The last line contains "S E" representing the start and end city. X, Y, S, E are all strings consisting of at most 10 alphanumeric characters.

Output

One line for each test case the least money Shua Shua have to pay. If it's impossible for him to finish the trip, just output -1.

Sample Input

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
4 4
Harbin Beijing 500
Harbin Shanghai 1000
Beijing Chengdu 600
Shanghai Chengdu 400
Harbin Chengdu

4 0
Harbin Chengdu

Sample Output

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
800
-1
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
概译:共有N个城市,M行里给出某市到另一个市(单向)的机票价格(这M行未必包含所有的N个城市),然后给出起始点和终点。这期间可以有一次机票打折机会,求解最小花费。如果到达不了,输出-1。

思路:显然的图题。如果没有打折这一条件的话就是有向图的最短路径,而打折条件是典型的、在每一步操作中可选可不选的条件类型,dp处理一下。也就是我们在求解最短路的过程中加上几条dp思想的语句来记录所需结果,此处最短路用的是spfa。另外注意一下这个题中,点的给出形式为字符串,我用的是STL中的map对其进行转化处理。
代码如下:

源代码:G++

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<map>
#include<vector>
#include<climits>
using namespace std;

typedef long long ll;
const long long inf = LLONG_MAX;

struct node
{
    int id, cost;
    node(int x, int y): id(x), cost(y) {}
};
int n, m, cnt; //点数、边数、在输入里出现过的城市数
ll dis[100005][2];//dp处理的距离
bool vis[100005];//spfa里负责记录是否在队列中
char ch1[15], ch2[15]; //城市1,城市2
//以下为最短路所需容器
map<string, int>mp;
vector<node>v[100005];
queue<int>q;

void spfa(int k)//求最短路
{
    for (int i = 1; i <= n; i++)
        dis[i][0] = dis[i][1] = inf;
    dis[k][0] = dis[k][1] = 0;
    //dis[i][0]代表到达i点时以前打过一次折的最小花费,即dis[城市2][0]就是结果,dis[i][1]是到达i点之前一直不打折的花费
    memset(vis, false, sizeof(vis));
    q.push(k);
    while (!q.empty())
    {
        int t = q.front(); q.pop();
        vis[t] = false;
        for (int i = 0; i < v[t].size(); i++)
        {
            node e = v[t][i];
            bool flag = false;
            if (dis[e.id][1] > dis[t][1] + e.cost) //常规操作,把dis[i][1]当成模板里的dis[i]就行……
            {
                flag = true;
                dis[e.id][1] = dis[t][1] + e.cost;
            }
            if (dis[e.id][0] > dis[t][0] + e.cost || dis[e.id][0] > dis[t][1] + e.cost / 2)
            {   //dp,之前打了折的花费加上这次的花费,与之前一直不打折这次打折的花费,取最小值为对于这个点的打过一次折以后的最小花费
                flag = true;
                dis[e.id][0] = min(dis[t][0] + e.cost, dis[t][1] + e.cost / 2);
            }
            if (flag && !vis[e.id]) //更新了花费且此点不在队列中时
            {
                vis[e.id] = true;
                q.push(e.id);
            }
        }
    }
}
int main()
{
    while (~scanf("%d%d", &n, &m))
    {
        //不要忘了各种清空
        cnt = 0;
        mp.clear();
        for (int i = 1; i <= n; i++)
            v[i].clear();
        //建图
        for (int i = 1; i <= m; i++)
        {
            int cost;//机票钱
            scanf("%s%s%d", ch1, ch2, &cost);
            //如果还没出现过这个城市,加进来,记录下来它的编号,简单起见第几个出现就是几了
            if (!mp[ch1]) mp[ch1] = ++cnt;
            if (!mp[ch2]) mp[ch2] = ++cnt;
            v[mp[ch1]].push_back(node(mp[ch2], cost)); //单向
        }
        scanf("%s%s", ch1, ch2); //起点终点
        if (!mp[ch1]) mp[ch1] = ++cnt;
        if (!mp[ch2]) mp[ch2] = ++cnt;
        spfa(mp[ch1]);//求解
        printf("%lld\n", dis[mp[ch2]][0] == inf ? -1 : dis[mp[ch2]][0]); //inf代表无法到达
    }
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-06-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ACM算法日常 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
浅谈 SPFA
SPFA 算法是 Bellman-Ford 算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环。SPFA 最坏情况下时间复杂度和朴素 Bellman-Ford 相同,为 O(VE)。
Clare613
2025/07/06
1371
[2019HDU多校第一场][HDU 6582][E. Path]
题意: t 组样例,n个点,m条边。i 行a到b距离c. 要求去掉最短路的最小代价。去掉每条路代价等于长度。
用户2965768
2019/08/01
3170
HDU3790 最短路径问题(dijkstra+思维)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790        其实就是裸的dij,只不过加了一个数组用来存花费,而且需要注意的是因为要求最短路程
Ch_Zaqdt
2019/01/11
7220
J - 【黄色】这题真的是模板题 Gym - 102072J 【 SPFA 】
J - 【黄色】这题真的是模板题 Gym - 102072J  在看完其他出题人出的毒瘤题之后,良心出题人终于看不下去了,决定出一道模板题来送给大家一个AC,那么,你们能不能接住这个送来的AC呢? 给出一个nn个结点mm条边的带权有向图,若图中存在负权回路直接输出"-1",否则输出点ss到每个点的最短路的长度,如果ss点不连通,输出"NoPath"。 Input 第一行输入三个值n,m,s(2≤n≤1000,m≤105,1≤s≤N)n,m,s(2≤n≤1000,m≤105,1≤s≤N) 接下来m
Lokinli
2023/03/09
2020
最短路专题2 | CodeForces 449B - SPFA算法
Jzzhu is the president of country A. There are n cities numbered from 1 to n in his country. City 1 is the capital of A. Also there are m roads connecting the cities. One can go from city to (and vise versa) using the -th road, the length of this road is . Finally, there are k train routes in the country. One can use the -th train route to go from capital of the country to city (and vise versa), the length of this route is . J是A国的总统,这个国家有n个城市。1是首都,有m条公路连接这些城市。然后,有k个火车线。城市到首都1的距离是。
ACM算法日常
2019/10/21
7270
图论--最短路--SPFA
SPFA算法(shortest path faster algorithm)算法是西南交通大学段凡丁于1994年发表的,它在Bellman-ford算法的基础上进行了改进,使其在能够处理待负权图的单元最短路径的基础上,时间复杂度大幅度降低。
风骨散人Chiam
2020/10/28
5190
POJ 3662 Telephone Lines【Dijkstra最短路+二分求解】
Telephone Lines Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7214 Accepted: 2638 Description Farmer John wants to set up a telephone line at his farm. Unfortunately, the phone company is uncooperative, so he needs to pay for som
Angel_Kitty
2018/04/09
8010
POJ 3159 Candies(SPFA+栈)差分约束
题意:给出m给 x 与y的关系。当中y的糖数不能比x的多c个。即y-x <= c  最后求fly[n]最多能比so[1] 多多少糖?
全栈程序员站长
2022/02/05
2200
HDU2066:一个人的旅行(Dijkstra)
Problem Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,0),很多事,还能丰富自己的阅历,还可以看美丽的风景……草儿想去很多地方,她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋,去纽约纯粹看雪景,去巴黎喝咖啡写信,去北京探望孟姜女……眼看寒假就快到了,这么一大段时间,可不能浪费啊,一定要给自己好好的放个假,可是也不能荒废了训练啊,所以草儿决定在要在最短的时间去一个自己想去的地方!因为草儿的家在一个小镇上,没有火车经过,所以她只能去邻近的城市坐火车(好可怜啊~)。
风骨散人Chiam
2020/10/28
4020
HDU 1874 畅通工程续 dijkstra+priority_queue
某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。 现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
ACM算法日常
2019/03/18
4290
HDU 3499 Flight(分层图最短路)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3499        题意是有n个城市,m条路线,然后有一张半价票,问从起点到终点的最小花费。    
Ch_Zaqdt
2019/01/28
6210
图论(洛谷刷题)
P3385 【模板】负环 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
用户11039529
2024/05/24
1300
图论(洛谷刷题)
PAT-CCCC练习:L2-001.紧急救援
作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。
ACM算法日常
2018/08/07
6520
10086. 「一本通 3.3 练习 3」Easy SSSP
给你一个图,问从源点到每个节点的最短路径分别是多少。 如果存在负权回路,只输出一行 -1;如果不存在负权回路,再求出一个点 S 到每个点的最短路的长度。如果 S 与这个点不连通,则输出 NoPath。
yzxoi
2022/09/19
2300
信息奥赛一本通1486: CH 6202 黑暗城堡 最短路径生成树计数
【题目描述】 知道黑暗城堡有 N 个房间,M 条可以制造的双向通道,以及每条通道的长度。
风骨散人Chiam
2020/10/28
4290
PAT (Advanced Level) Practice 1030 Travel Plan (30分)
A traveler's map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path between his/her starting city and the destination. If such a shortest path is not unique, you are supposed to output the one with the minimum cost, which is guaranteed to be unique.
glm233
2020/09/28
2940
Tricks Device (hdu 5294 最短路+最大流)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 124 Accepted Submission(s): 27
全栈程序员站长
2022/07/10
2420
L2-001 紧急救援 (25 分)(Dijkstra应用)
作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。
Here_SDUT
2022/08/08
5420
洛谷P3953 逛公园(dp 拓扑排序)
首先不难想到一个思路,\(f[i][j]\)表示到第\(i\)个节点,与最短路之差长度为\(j\)的路径的方案数
attack
2018/12/05
6210
hdu 4063 Aircraft 计算几何+最短路
易知最短路一定是以圆心或者两圆交点作为中间点到达的。所以把这些点拿出来建图跑最短路就够了。
全栈程序员站长
2022/07/07
2700
推荐阅读
相关推荐
浅谈 SPFA
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验