HDU 3499 Flight spfa+dp
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
Input
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
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
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的更多相关文章
- 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 ...
- HDU 4433 locker(SPFA+DP)
题目链接 去年区域赛的题目,早就看过题目了,又是过了好久了... 这题状态转移,一看就知道应该是 线性的那种,不过细节真的不好处理,一直没想出怎么搞,期间也看过题解,好像没太看懂... dp[i][j ...
- 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,求从起点到终点的最短距离. 解题分析: 分层图最短路 ...
- 【BZOJ1003】1003: [ZJOI2006]物流运输trans SPFA+DP
Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格 ...
- HDU 1011 树形背包(DP) Starship Troopers
题目链接: HDU 1011 树形背包(DP) Starship Troopers 题意: 地图中有一些房间, 每个房间有一定的bugs和得到brains的可能性值, 一个人带领m支军队从入口(房 ...
- BZOJ 1003 [ZJOI2006]物流运输trans SPFA+DP
题意:链接 方法:SPFA+DP 解析:挺好的题目.因为数据范围较小所以用这样的方式能够搞,只是也是挺不好想的. 我们定义cost(i,j)表示从第i天走到第j天运用同一种方式的最小花费,然后因为数据 ...
- hdu 2296 aC自动机+dp(得到价值最大的字符串)
Ring Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- HDU 4778 状压DP
一看就是状压,由于是类似博弈的游戏.游戏里的两人都是绝对聪明,那么先手的选择是能够确定最终局面的. 实际上是枚举最终局面情况,0代表是被Bob拿走的,1为Alice拿走的,当时Alice拿走且满足变换 ...
随机推荐
- ios 显示其他app的购买页面
using UnityEngine; using System.Collections; using System.Runtime.InteropServices ; public class IOS ...
- Docker 总结
版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] Docker总结 简单介绍 1 Docker 架构 安装和环境配置 1 mac 11 brew安装 11 dmg文件安装 1 ...
- 关于pagerank算法的一点点总结
1. PageRank算法每个顶点收敛的值与每个点的初值是没有关系的,每个点随便赋初值. 2.像q=0.8这样的阻尼系数已经解决了PageRank中处在的孤立点问题.黑洞效应问题. 3.当有那个点进行 ...
- Java中的注释
代码注释是架起程序设计者与程序阅读者之间的通信桥梁,最大限度的提高团队开发合作效率.也是程序代码可维护性的重要环节之一.所以我们不是为写注释而写注释.下面说一下Javadoc注释规范以及楼主在J2EE ...
- Spring.net 学习IOC------准备
在学习spring.net开始时,我们首先要下载spring.net所用到的类库: Common.Logging.dll(必要)Spring.Core.dll(必要)Spring.Data.dllSp ...
- ubuntu 上配置python +selenium环境
1.ubuntu 自带了python, 可以打开终端输入python 回车后如果显示版本信息就说明已经安装 2.安装安装python setup tools apt-get install pytho ...
- 常用Oracle分析函数详解 [http://www.cnblogs.com/benio/archive/2011/06/01/2066106.html]
学习步骤:1. 拥有Oracle EBS demo 环境 或者 PROD 环境2. copy以下代码进 PL/SQL3. 配合解释分析结果4. 如果网页有点乱请复制到TXT中查看 /*假设一个经理 ...
- HDU 5758 Explorer Bo
思维,树形$dp$. 首先选择一个度不为$0$的节点作为根节点,将树无根转有根. 这题的突破口就是要求瞬间移动的次数最少. 次数最少,必然是一个叶子节点走到另一个叶子节点,然后瞬间移动一次,再从一个叶 ...
- ios 实现在tableViewCell上面添加长按手势 删除该条cell以及列表后台数据等
自己的代码 需要 把属性更改成自己要使用的 //创建长按手势 在cellForRowAtIndexPath代理方法中 UILongPressGestureRecognizer *longPres ...
- HDU2363 最短路+贪心
Cycling Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...