HDU - 3499 Flight 双向SPFA+枚举中间边
Flight
InputThere 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.
OutputOne 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
4 4
Harbin Beijing 500
Harbin Shanghai 1000
Beijing Chengdu 600
Shanghai Chengdu 400
Harbin Chengdu 4 0
Harbin Chengdu
Sample Output
800
-1
Hint
In the first sample, Shua Shua should use the card on the flight from
Beijing to Chengdu, making the route Harbin->Beijing->Chengdu have the
least total cost 800. In the second sample, there's no way for him to get to
Chengdu from Harbin, so -1 is needed. 题意:ShuaShua要从一个城市到另一个城市,给出每两城市之间的花费(有向),ShuaShua可以有一次半价的机会,求最小花费。
思路:最短路径问题。开始想到求出最短路后选择其中最大的边/2,但其实错误,很容易举出反例:路径1:1 1 100 路径2:30 30 30 开始时102 90选择花费少的路径2,减半价后52 75路径1花费反而相对更少。
因此我们可以换一种思路,以起点和终点为单源分别求出到各点的最短路,然后枚举每一条边作为中间边,dis[u]+w(u,v)/2+diss[v]的最小值为解。
#include<stdio.h>
#include<string.h>
#include<vector>
#include<deque>
#include<map>
#include<string>
#define MAX 100005
#define MAXX 500005
#define INF 10000000000000000
using namespace std; struct Node{
int v,w;
}node;
vector <Node> edge[MAX],redge[MAX];
map<string,int> mp;
long long dis[MAX],diss[MAX],b[MAX],u[MAXX],v[MAXX],w[MAXX];
char s1[MAX],s2[MAX];
int n; void spfa1(int k)
{
int i;
deque<int> q;
for(i=;i<=n;i++){
dis[i]=INF;
}
memset(b,,sizeof(b));
b[k]=;
dis[k]=;
q.push_back(k);
while(q.size()){
int u=q.front();
for(i=;i<edge[u].size();i++){
int v=edge[u][i].v;
long long w=edge[u][i].w;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
if(b[v]==){
b[v]=;
if(dis[v]>dis[u]) q.push_back(v);
else q.push_front(v);
}
}
}
b[u]=;
q.pop_front();
}
} void spfa2(int k)
{
int i;
deque<int> q;
for(i=;i<=n;i++){
diss[i]=INF;
}
memset(b,,sizeof(b));
b[k]=;
diss[k]=;
q.push_back(k);
while(q.size()){
int u=q.front();
for(i=;i<redge[u].size();i++){
int v=redge[u][i].v;
long long w=redge[u][i].w;
if(diss[v]>diss[u]+w){
diss[v]=diss[u]+w;
if(b[v]==){
b[v]=;
if(diss[v]>diss[u]) q.push_back(v);
else q.push_front(v);
}
}
}
b[u]=;
q.pop_front();
}
} int main()
{
int m,bg,ed,t,i,j;
while(~scanf("%d%d",&n,&m)){
t=;
for(i=;i<=n;i++){
edge[i].clear();
redge[i].clear();
mp.clear();
}
memset(u,,sizeof(u));
memset(v,,sizeof(v));
memset(w,,sizeof(w));
for(i=;i<=m;i++){
scanf(" %s%s%lld",s1,s2,&w[i]);
if(!mp[s1]) mp[s1]=++t;
if(!mp[s2]) mp[s2]=++t;
u[i]=mp[s1];
v[i]=mp[s2];
node.v=mp[s2];
node.w=w[i];
edge[mp[s1]].push_back(node);
node.v=mp[s1];
redge[mp[s2]].push_back(node);
}
scanf(" %s%s",s1,s2);
if(!mp[s1]) mp[s1]=++t;
if(!mp[s2]) mp[s2]=++t;
bg=mp[s1],ed=mp[s2];
spfa1(bg);
spfa2(ed);
long long min=INF;
for(i=;i<=m;i++){
if(dis[u[i]]==INF||dis[v[i]]==INF) continue;
if(dis[u[i]]+diss[v[i]]+w[i]/<min) min=dis[u[i]]+diss[v[i]]+w[i]/;
}
if(min==INF) printf("-1\n");
else printf("%lld\n",min);
}
return ;
}
HDU - 3499 Flight 双向SPFA+枚举中间边的更多相关文章
- HDU 3499 Flight spfa+dp
Flight Time Limit : 20000/10000ms (Java/Other) Memory Limit : 65535/65535K (Java/Other) Total Subm ...
- hdu 3499 Flight (最短路径)
Flight Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Su ...
- hdu 3499 flight 【分层图】+【Dijkstra】
<题目链接> 题目大意: 现在给你一些点,这些点之间存在一些有向边,每条边都有对应的边权,有一次机会能够使某条边的边权变为原来的1/2,求从起点到终点的最短距离. 解题分析: 分层图最短路 ...
- BZOJ 1726 [Usaco2006 Nov]Roadblocks第二短路:双向spfa【次短路】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1726 题意: 给你一个无向图,求次短路. 题解: 两种方法. 方法一: 一遍spfa,在s ...
- 【NOIP2009 T3】 最佳贸易 (双向SPFA)
C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通行的道路,一部分为双向通行的道路,双向通行的道 ...
- HDU 1401 Solitaire 双向DFS
HDU 1401 Solitaire 双向DFS 题意 给定一个\(8*8\)的棋盘,棋盘上有4个棋子.每一步操作可以把任意一个棋子移动到它周围四个方向上的空格子上,或者可以跳过它四个方向上的棋子(就 ...
- find the longest of the shortest (hdu 1595 SPFA+枚举)
find the longest of the shortest Time Limit: 1000/5000 MS (Java/Others) Memory Limit: 32768/32768 ...
- HDU - 3499 -(Dijkstra变形+枚举边)
Recently, Shua Shua had a big quarrel with his GF. He is so upset that he decides to take a trip to ...
- Flight HDU - 3499 (分层最短路)
Recently, Shua Shua had a big quarrel with his GF. He is so upset that he decides to take a trip to ...
随机推荐
- 使用IntelliJ IDEA 15和Maven创建Java Web项目(转)
1. Maven简介 相对于传统的项目,Maven 下管理和构建的项目真的非常好用和简单,所以这里也强调下,尽量使用此类工具进行项目构建, 它可以管理项目的整个生命周期. 可以通过其命令做所有相关的工 ...
- Java 内存分配全面浅析(转)
本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java.这类文章网上有很多,但大多比较零碎.本文从认知过程角度出发,将带给读者一个系统的介绍. 进入正题前首先要知道的是Java程 ...
- OCR光学字符识别--STN-OCR 测试
1.同文章中建议的使用ubuntu-python隔离环境,真的很好用 参照:http://blog.topspeedsnail.com/archives/5618启动虚拟环境:source env/b ...
- linux复制和移动
复制: -f 强制覆盖同名文件 -r 按递归方式保留原目录结构复制文件 cp -Rf /home/user1/* /root/temp/ 将/home/user1目录下的所有东西拷到/root ...
- Apache NiFi 开发 处理器使用说明
NIFI的使用: 注意:FlowFile由[属性]和[内容]组成,在解析的过程中这个概念非常重要,因为有些组件操作的是属性,有些组件操作的是内容,在配置组件时Destination配置项的选择很重要, ...
- 电话聊天狂人 【STL】
7-2 电话聊天狂人(25 分) 给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤105),为通话记录条数.随后N行,每行给出一条通话记录.简单起 ...
- 在VS2015中的SDL2.0开发环境搭建
写本文的目的在于使用网络上的教程及官方的教程(如:http://www.willusher.io/sdl2%20tutorials/2013/08/15/lesson-0-visual-studio) ...
- 【LeetCode】种花问题
假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有.可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去. 给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花 ...
- 2013各大IT公司薪资标准
以此鼓励自己 :http://jinhua.19lou.com/forum-874-thread-115901362964023509-1-1.html 以下三个是老大级别的公司 [微软] 研 ...
- BZOJ 1726 [Usaco2006 Nov]Roadblocks第二短路:双向spfa【次短路】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1726 题意: 给你一个无向图,求次短路. 题解: 两种方法. 方法一: 一遍spfa,在s ...