Flight

Time Limit : 20000/10000ms (Java/Other)   Memory Limit : 65535/65535K (Java/Other)
Total Submission(s) : 5   Accepted Submission(s) : 1

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

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

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.
 
/*
这题刚开始我以为只要先找到最短路径,然后再把机票最贵的折半就行了,
后来发现,不一定。。。。这样最便宜(。﹏。)
上网搜了一下,有的是spfa+dp有的分层图,我决定把两种都写一遍(๑•̀ㅂ•́)و✧
*/ /* spfa+dp
dis[0][i]表示到i点折半的花费 dis[1][i]表示到i点没用过折半的花费
这题还要注意的是花费总额已经超出int范围,要用long long
然而我inf最大值没有改成LLONG_MAX错了好几次
*/ #include <iostream>
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<algorithm>
#include<climits>
using namespace std;
long long dis[][];
bool vis[];
struct node
{
int num,d;
node(int a,int b){num=a; d=b;}
};
vector<node> s[];
int n,m;
const long long inf=LLONG_MAX;
map<string,int> mp;
void spfa(int k)
{
for(int i=;i<=n;i++) dis[i][]=dis[i][]=inf,vis[i]=;
queue<int> Q;
Q.push(k);
vis[k]=;
dis[k][]=dis[k][]=;
while(!Q.empty())
{
int u=Q.front();
Q.pop();
vis[u]=;
for(int i=;i<s[u].size();i++)
{
bool flag=;
if (dis[s[u][i].num][]>dis[u][]+s[u][i].d)
{
flag=;
dis[s[u][i].num][]=dis[u][]+s[u][i].d;
}
if (dis[s[u][i].num][]>dis[u][]+s[u][i].d || dis[s[u][i].num][]>dis[u][]+s[u][i].d/)
{
dis[s[u][i].num][]=min(dis[u][]+s[u][i].d,dis[u][]+s[u][i].d/);
flag=;
}
if(flag && !vis[s[u][i].num])
{
vis[s[u][i].num]=;
Q.push(s[u][i].num);
}
}
}
return;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
int l=,d;
char ch2[],ch1[];
for(int i=;i<=n;i++) s[i].clear();
mp.clear();
for(int i=;i<=m;i++)
{
scanf("%s %s %d",&ch1,&ch2,&d);
if (!mp[ch1]) mp[ch1]=++l;
if (!mp[ch2]) mp[ch2]=++l;
s[mp[ch1]].push_back( node(mp[ch2],d) );
}
scanf("%s %s",&ch1,&ch2);
if (!mp[ch1]) mp[ch1]=++l;//可能m=0,所以有可能开始和结束城市都没有编号
if (!mp[ch2]) mp[ch2]=++l;
int scity=mp[ch1]; //开始的城市编号
int ecity=mp[ch2]; //相要到达的城市编号
spfa(scity);
if (dis[ecity][]==inf) printf("-1\n");
else printf("%lld\n",dis[ecity][]);
}
return ;
}

最后还是拉了一段代码,(⊙﹏⊙)b

/*

转自:http://yomean.blog.163.com/blog/static/189420225201110282390985/

一看就想到了分层图,不过如果用分层图,有点杀鸡用牛刀的感觉,因为只有两层。但我还是写了,最后AC了。不过网上很多人都是用建反两向边求解。
而对于分层图求最短路径问题,我们要注意的是,层与层之间的连线都是单向的,而且是从下一层指向上一层,而我们求最短路径的时候,起点总是在下一层,而终点总是在上一层,所以我们可以将经过层与层之间的特殊边的数目控制在n - 1(n是层数)。 */
#include<iostream>
#include<cstdio>
#include<string>
#include<queue>
#include<map>
#include<vector>
#define N 100005
#define inf (_I64_MAX)/2
using namespace std;
int n,m;
int head[*N],vis[*N];
int now,index,k;
__int64 dis[*N];
char name[N][];
map<string,int>M;
struct node{
int v,w,next;
}edge[*N];
void addedge(int u,int v,int w)
{
edge[index].v=v;
edge[index].w=w;
edge[index].next=head[u];
head[u]=index++;
}
struct cmp{
bool operator()(int a,int b){
return dis[a]>dis[b];
}
};
priority_queue<int,vector<int>,cmp>Q;
void init()
{
while(!Q.empty()) Q.pop();
M.erase(M.begin(),M.end());
for(int i=;i<*n;i++){
vis[i]=false;
head[i]=-;
}
now=;
index=;
}
void dij(int s,int e)
{
for(int i=;i<=*n;i++){
dis[i]=inf;vis[i]=false;
}
dis[s]=;
vis[s]=true;
Q.push(s);
while(!Q.empty()){
int u=Q.top();
Q.pop();
if(u==e){
printf("%I64d\n",dis[u]);
return;
}
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
int w=edge[i].w;
if(!vis[v] && dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
Q.push(v);
}
}
}
}
int main(void)
{
string a,b;
int x,y,c;
while(cin>>n>>m)
{
init();
for(int i=;i<m;i++){
cin>>a>>b>>c;
if(M.find(a)==M.end()) M[a]=now++;
if(M.find(b)==M.end()) M[b]=now++;
addedge(M[a],M[b],c);
addedge(M[a]+n,M[b]+n,c);
addedge(M[a]+n,M[b],c/);
}
cin>>a>>b;
__int64 ans=inf;
if(M.find(a)==M.end() || M.find(b)==M.end()){
puts("-1");continue;
}
else dij(M[a]+n,M[b]);
}
return ;
}

HDU 3499 Flight spfa+dp的更多相关文章

  1. HDU - 3499 Flight 双向SPFA+枚举中间边

    Flight Recently, Shua Shua had a big quarrel with his GF. He is so upset that he decides to take a t ...

  2. HDU 4433 locker(SPFA+DP)

    题目链接 去年区域赛的题目,早就看过题目了,又是过了好久了... 这题状态转移,一看就知道应该是 线性的那种,不过细节真的不好处理,一直没想出怎么搞,期间也看过题解,好像没太看懂... dp[i][j ...

  3. hdu 3499 Flight (最短路径)

    Flight Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Su ...

  4. hdu 3499 flight 【分层图】+【Dijkstra】

    <题目链接> 题目大意: 现在给你一些点,这些点之间存在一些有向边,每条边都有对应的边权,有一次机会能够使某条边的边权变为原来的1/2,求从起点到终点的最短距离. 解题分析: 分层图最短路 ...

  5. 【BZOJ1003】1003: [ZJOI2006]物流运输trans SPFA+DP

    Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格 ...

  6. HDU 1011 树形背包(DP) Starship Troopers

    题目链接:  HDU 1011 树形背包(DP) Starship Troopers 题意:  地图中有一些房间, 每个房间有一定的bugs和得到brains的可能性值, 一个人带领m支军队从入口(房 ...

  7. BZOJ 1003 [ZJOI2006]物流运输trans SPFA+DP

    题意:链接 方法:SPFA+DP 解析:挺好的题目.因为数据范围较小所以用这样的方式能够搞,只是也是挺不好想的. 我们定义cost(i,j)表示从第i天走到第j天运用同一种方式的最小花费,然后因为数据 ...

  8. hdu 2296 aC自动机+dp(得到价值最大的字符串)

    Ring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  9. HDU 4778 状压DP

    一看就是状压,由于是类似博弈的游戏.游戏里的两人都是绝对聪明,那么先手的选择是能够确定最终局面的. 实际上是枚举最终局面情况,0代表是被Bob拿走的,1为Alice拿走的,当时Alice拿走且满足变换 ...

随机推荐

  1. unity3D中重要函数

    Update 当MonoBehaviour启用时,其Update在每一帧被调用. LateUpdate 当Behaviour启用时,其 LateUpdate在每一帧被调用. FixedUpdate 当 ...

  2. Ansible hostvars

    1.  inventory hosts file 中的server 变量会覆盖group变量. hostvars: { "iaas_name": "test", ...

  3. vscode: Visual Studio Code 常用快捷键

    vscode: Visual Studio Code 常用快捷键 主命令框 F1 或 Ctrl+Shift+P: 打开命令面板.在打开的输入框内,可以输入任何命令,例如: 按一下 Backspace ...

  4. informix 存储过程结构

    1.简介         存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中.用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行 ...

  5. 推荐几个好的 Maven 常用仓库网址

    注意,以下内容转载自:推荐几个好的 Maven 常用仓库网址 Maven 确确实实是个好东西,用来管理项目显得很方便,但是如果是通过 Maven 来远程下载 JAR 包的话,我宿舍的带宽是4兆的,4个 ...

  6. 2015 Syrian Private Universities Collegiate Programming Contest 题解

    题目在这里>_< 发现这场比赛在网上没有完整的题解,甚至连题目代码都没人贴出来(大概是因为题目太水了吧...).所以宝宝就来写个题解,也就当作成长记录了233333 A. Window 题 ...

  7. SQL中判断字符串中包含字符的方法

    通过2个函数CHARINDEX和PATINDEX以及通配符的灵活使用 函数:CHARINDEX和PATINDEX CHARINDEX:查某字符(串)是否包含在其他字符串中,返回字符串中指定表达式的起始 ...

  8. 转:详解JMeter正则表达式(1)

    1.概览 JMeter中包含范本匹配软件Apache Jakarta ORO .在Jakarta网站上有一些关于它的文档,例如a summary of the pattern matching cha ...

  9. openstack私有云布署实践【12.1 网络Neutron-controller节点配置(科兴环境)】

    网络这一块推荐使用的是 Neutron--LinuxBirdge的Ha高可用,此高可用方案对Public作用不是很大,Public只用到DHCP,而Private则会用到L3 Agent,则此方案是有 ...

  10. Linux系统安装rar压缩软件

    将 hebaodans.com 目录打包为 hebaodans.rar # rar a hebaodans.rar ./hebaodans.com/ 解压 hebaodans.rar 到当前目录 # ...