NEU 1664 传送(最短路基础 堆优化Dijkstra)
题目描述
小A最近喜欢上一款游戏:游戏把地图分了一些区域,这些区域可能会重叠,也可能不会。
游戏中有一项传送技能,改传送技能只能将在同一区域的两个地方使用。小A可以利用区域中重叠部分来实现从某一区域到另一个区域的移动。
当然技能会消耗魔法值,对于同一区域内两点,消耗的魔法值是相同的。如下图:
有红蓝两个区域,共4个地点1 2 3 4,假设在红色区域移动只需消耗a1点魔法值,在蓝色区域间移动需花费a2点魔法值,那么1和2之间或者1和3之间都需花费a1点魔法,2和4或者3和4之间都需要a2点魔法,2和3之间选择消耗a1点魔法也可以选择消耗a2点魔法。
现在小A在S点接到了一个任务,需要到达F点去做任务,再到P点交任务。
现在让你求一下完成该任务,需要因为传送消耗的魔法值至少为多少。
当然有些地方需要花RMB才能到达,即你从S点无论如何也无法到达F点去做任务,或者F点无法到达P点。因为双11,小A已经没有RMB了,这是你只需告诉他“Poor guy, you don’t have enough Money!”。
输入
多组样例输入(不会超过10组)
对于每一组样例:
第一行有五个整数 n m S F P 表示有n个地点和m个区域(2<=n<=100000) (0<m<1000000)。S F P为题目中所述的地点编号。(地点编号为:1,2,3......,n).
接下来每行描述的是每一个区域的信息,
ai bi 表示 在第i块区域内需要消耗ai点魔法值,第i各区域有bi个地点,然后有bi个数,代表第i个区域内第地点编号。(1<=ai<=1000000000, bi>0) .
保证所有bi的和小于1000000.
输出
如果无解,则输出“Poor guy, you don’t have enough Money!”(引号中的内容)。
否则就输出最少的消耗的魔法量。
样例输入
4 2 1 4 2
3 3 1 2 3
5 3 2 3 4
样例输出
13 思路:把区域当做节点,穿过某个区域抽象成路过某个节点,进入该节点话费为ai,出节点免费,链接点和区域,然后以目标点(中间点)为原点做一遍单源最短路,我用的是Dijkstra,最后时间为7000+ms,空间为50000kb+,空间还好,是提交的里面几乎最小的,但是时间很不满意,应该还有更好的方法,知道了来更新。
(update001:下面这个是错误代码,不要参考)
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
const int maxl=;
const int maxn=;
using namespace std;
int n,m,s,t,p;
int lin[maxn],cnt=;
struct str
{
int y;
int z;
int next;
}e[maxl];
void insert(int x,int y,int z)
{
cnt++;
e[cnt].next=lin[x];
lin[x]=cnt;
e[cnt].y=y;
e[cnt].z=z;
}
struct strdis
{
int x;
long long dis;
bool operator<(const strdis& a)const{return dis<a.dis;}
void set(int xx,int diss){x=xx;dis=diss;}
}temp,noww;
//bool operator <(const strdis &a,const strdis &b){return a.dis<b.dis;}
priority_queue <strdis> q;
bool vis[maxn];
long long dis[maxn];
int main()
{
while(scanf("%d%d%d%d%d",&n,&m,&s,&p,&t)!=EOF)
{
memset(lin,,sizeof(lin));cnt=;
memset(vis,,sizeof(vis));
for(int i=;i<=m;i++)
{
int ai,bi,x;
scanf("%d%d",&ai,&bi);
for(int j=;j<=bi;j++)
{
scanf("%d",&x);
insert(x,n+i,ai);
insert(n+i,x,);
}
}
temp.set(p,);
q.push(temp);
memset(dis,0x3f,sizeof(dis));
dis[p]=;
while(!q.empty())
{
noww=q.top();
q.pop();
int nn=noww.x;
if(vis[nn])continue;
vis[nn]=;
for(int i=lin[nn];i;i=e[i].next)
{
int u=e[i].y;
if(dis[u]>dis[nn]+e[i].z)
{
dis[u]=dis[nn]+e[i].z;
temp.set(u,dis[u]);
q.push(temp);
}
}
}
if((!vis[s])||(!vis[t]))
{
printf("Poor guy, you don't have enough Money!\n");
}
else
{
printf("%lld\n",dis[s]+dis[t]);
}
} return ;
}
Dijkstra
提交了五次,前两次是忘记去掉打表。。。第三次是复制粘贴的答案字符串里面有不对的字符,第四次是重定义符号弄反了,第五次是没有看到多组数据。
恩,re小王子又回来了。。。。要注意。
哦,既然写了Dijkstra,就要说下如何堆优化,
其实不用担心如何更新堆里边dis的值,没必要,只需要把新的值push进去就好了,因为访问次优的时候,那个点已经vis过了。。。就是空间上浪费点儿。。。不知道怎么解决
update-------------------------------------------------------------------------------------2016.02.11
我的代码比别人的慢四倍,自己怎么找都找不到问题,学长一下就看了出来。。。
原来的代码有一个符号错了,就是重定义小于号那里,因为默认是大根堆,也就是最大的先出来,我们需要最短的,于是需要反着定义
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
const int maxl=;
const int maxn=;
using namespace std;
int n,m,s,t,p;
int lin[maxn],cnt=;
struct str
{
int y;
int z;
int next;
}e[maxl];
void insert(int x,int y,int z)
{
cnt++;
e[cnt].next=lin[x];
lin[x]=cnt;
e[cnt].y=y;
e[cnt].z=z;
}
struct strdis
{
int x;
long long dis;
bool operator<(const strdis& a)const{return dis>a.dis;}
}noww;
//bool operator <(const strdis &a,const strdis &b){return a.dis<b.dis;}
priority_queue <strdis> q;
bool vis[maxn];
long long dis[maxn];
int main()
{
while(scanf("%d%d%d%d%d",&n,&m,&s,&p,&t)!=EOF)
{
memset(lin,,sizeof(lin));cnt=;
memset(vis,,sizeof(vis));
for(int i=;i<=m;i++)
{
int ai,bi,x;
scanf("%d%d",&ai,&bi);
for(int j=;j<=bi;j++)
{
scanf("%d",&x);
insert(x,n+i,ai);
insert(n+i,x,);
}
}
q.push((strdis){p,});
memset(dis,0x3f,sizeof(dis));
dis[p]=;
while(!q.empty())
{
noww=q.top();
q.pop();
int nn=noww.x;
if(vis[nn])continue;
vis[nn]=;
for(int i=lin[nn];i;i=e[i].next)
{
int u=e[i].y;
if(dis[u]>dis[nn]+e[i].z)
{
dis[u]=dis[nn]+e[i].z;
q.push((strdis){u,dis[u]});
}
}
}
if((!vis[s])||(!vis[t]))
{
printf("Poor guy, you don't have enough Money!\n");
}
else
{
printf("%lld\n",dis[s]+dis[t]);
}
} return ;
}
NEU 1664 传送(最短路基础 堆优化Dijkstra)的更多相关文章
- BZOJ 3040 最短路 (堆优化dijkstra)
这题不是裸的最短路么?但是一看数据范围就傻了.点数10^6,边数10^7.这个spfa就别想了(本来spfa就是相当不靠谱的玩意),看来是要用堆优化dijkstra了.但是,平时写dijkstra时为 ...
- 最短路模板|堆优化Dijkstra,SPFA,floyd
Ⅰ:Dijkstra单源点最短路 1.1Dijkstra const int MAX_N = 10000; const int MAX_M = 100000; const int inf = 0x3f ...
- POJ 3635 - Full Tank? - [最短路变形][手写二叉堆优化Dijkstra][配对堆优化Dijkstra]
题目链接:http://poj.org/problem?id=3635 题意题解等均参考:POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]. 一些口胡: ...
- 【堆优化Dijkstra+字典序最短路方案】HDU1385-Minimum Transport Cost
[题目大意] 给出邻接矩阵以及到达各个点需要付出的代价(起点和终点没有代价),求出从给定起点到终点的最短路,并输出字典序最小的方案. [思路] 在堆优化Dijkstra中,用pre记录前驱.如果新方案 ...
- 堆优化Dijkstra计算最短路+路径计数
今天考试的时候遇到了一道题需要路径计数,然而蒟蒻从来没有做过,所以在考场上真的一脸懵逼.然后出题人NaVi_Awson说明天考试还会卡SPFA,吓得我赶紧又来学一波堆优化的Dijkstra(之前只会S ...
- PAT-1030 Travel Plan (30 分) 最短路最小边权 堆优化dijkstra+DFS
PAT 1030 最短路最小边权 堆优化dijkstra+DFS 1030 Travel Plan (30 分) A traveler's map gives the distances betwee ...
- 【bzoj4070】[Apio2015]雅加达的摩天楼 set+堆优化Dijkstra
题目描述 印尼首都雅加达市有 N 座摩天楼,它们排列成一条直线,我们从左到右依次将它们编号为 0 到 N−1.除了这 N 座摩天楼外,雅加达市没有其他摩天楼. 有 M 只叫做 “doge” 的神秘生物 ...
- UVA - 11374 - Airport Express(堆优化Dijkstra)
Problem UVA - 11374 - Airport Express Time Limit: 1000 mSec Problem Description In a small city c ...
- BZOJ5415[Noi2018]归程——kruskal重构树+倍增+堆优化dijkstra
题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 n 个节点.m 条边的无向连通图(节点的编号从 1 至 n).我们依次用 l,a 描述一条边的长度.海 ...
随机推荐
- ajax获取跨域数据
1.效果图 2.源码 <%@ page contentType="text/html;charset=UTF-8" language="java" %&g ...
- 破解VIP会员视频集合
浏览器安装暴力猴扩展即可使用 // ==UserScript== // @name 破解VIP会员视频集合 // @namespace https://greasyfork.org/zh-CN/use ...
- Python 之 基础知识(二)
一.分支运算 在Python 2.x中判断不等于还可以用<> if语句进阶:elif if 条件1: ...... elif 条件2: ...... else: ...... 二.逻辑运算 ...
- 杭电 2035 人见人爱A^B【快速幂取模】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2035 解题思路:这一题数据不大,可以用同余来做,也可以用快速幂来做 反思:定义成 #include&l ...
- HttpServletRequest二三事
缘由 在项目中,闲来无聊写了个bug LOGGER.info("前端请求,request:{}",JSON.toJSONString(request)); 好像还好是吧,来我告诉你 ...
- SSH启动失败解决方法
今天连接linux时居然连不上,报错信息是: 查了一下终于找到了解决办法,只需要一些命令 : cd /etc/ssh sudo chmod 644 ./* sudo chmod 600 ssh_hos ...
- android生成sdk.jar 小工具
net.sf.fjep.fatjar_0.0.31.jar 生成jar的工具 把这个net.sf.fjep.fatjar_0.0.31.jar到Eclipse的plugins中,从启Eclipse.点 ...
- PHP学习总结(7)——PHP入门篇之PHP注释
注释 在PHP中也有注释语句:用双斜杠(//)来表示.其它语言中,Html中使用<!--注释语句-->,CSS中使用/*注释语句*/.如下面代码: <?php//输出hi,imooc ...
- spring的bean注入扫瞄方法和mybatis的dao bean注入扫描方法
spring的bean注入扫面方法:@ComponentScan(basePackages = "com.pingan.property.icore.pap.*")mybatis的 ...
- python的数据可视化库 matplotlib 和 pyecharts
Matplotlib大家都很熟悉 不谈. ---------------------------------------------------------------------------- ...