题目描述

小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)的更多相关文章

  1. BZOJ 3040 最短路 (堆优化dijkstra)

    这题不是裸的最短路么?但是一看数据范围就傻了.点数10^6,边数10^7.这个spfa就别想了(本来spfa就是相当不靠谱的玩意),看来是要用堆优化dijkstra了.但是,平时写dijkstra时为 ...

  2. 最短路模板|堆优化Dijkstra,SPFA,floyd

    Ⅰ:Dijkstra单源点最短路 1.1Dijkstra const int MAX_N = 10000; const int MAX_M = 100000; const int inf = 0x3f ...

  3. POJ 3635 - Full Tank? - [最短路变形][手写二叉堆优化Dijkstra][配对堆优化Dijkstra]

    题目链接:http://poj.org/problem?id=3635 题意题解等均参考:POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]. 一些口胡: ...

  4. 【堆优化Dijkstra+字典序最短路方案】HDU1385-Minimum Transport Cost

    [题目大意] 给出邻接矩阵以及到达各个点需要付出的代价(起点和终点没有代价),求出从给定起点到终点的最短路,并输出字典序最小的方案. [思路] 在堆优化Dijkstra中,用pre记录前驱.如果新方案 ...

  5. 堆优化Dijkstra计算最短路+路径计数

    今天考试的时候遇到了一道题需要路径计数,然而蒟蒻从来没有做过,所以在考场上真的一脸懵逼.然后出题人NaVi_Awson说明天考试还会卡SPFA,吓得我赶紧又来学一波堆优化的Dijkstra(之前只会S ...

  6. PAT-1030 Travel Plan (30 分) 最短路最小边权 堆优化dijkstra+DFS

    PAT 1030 最短路最小边权 堆优化dijkstra+DFS 1030 Travel Plan (30 分) A traveler's map gives the distances betwee ...

  7. 【bzoj4070】[Apio2015]雅加达的摩天楼 set+堆优化Dijkstra

    题目描述 印尼首都雅加达市有 N 座摩天楼,它们排列成一条直线,我们从左到右依次将它们编号为 0 到 N−1.除了这 N 座摩天楼外,雅加达市没有其他摩天楼. 有 M 只叫做 “doge” 的神秘生物 ...

  8. UVA - 11374 - Airport Express(堆优化Dijkstra)

    Problem    UVA - 11374 - Airport Express Time Limit: 1000 mSec Problem Description In a small city c ...

  9. BZOJ5415[Noi2018]归程——kruskal重构树+倍增+堆优化dijkstra

    题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 n 个节点.m 条边的无向连通图(节点的编号从 1 至 n).我们依次用 l,a 描述一条边的长度.海 ...

随机推荐

  1. C#中图片转换为Base64编码,Base64编码转换为图片

    #region 图片转为base64编码的字符串 public string ImgToBase64String(string Imagefilename) { try { Bitmap bmp = ...

  2. [hihocoder][Offer收割]编程练习赛49

    相似颜色 #pragma comment(linker, "/STACK:102400000,102400000") #include<stdio.h> #includ ...

  3. 学习js与css 写个2048

    学习阶段,还是写点小东西练练手学的有意思一点,今天用栅格布局做了一个2048,但是移动动画和合并特效没有做,只简单的实现了一下功能. 记录一下学习的过程. 1.入口函数,初始化界面,我这里是直接是一个 ...

  4. 【Oracle】查询当前SCN

    介绍两种方式: 一.sys用户下: select current_scn from v$database; select dbms_flashback.get_system_change_number ...

  5. 从Spark1.6到Spark2.1,Logging该何去何从

    大家都知道spark 1.6.0版本比较稳定,也比较流行. 我们项目组也是,最初用的就是这个版本. 这段时间,项目组引入spark 2.1.0版本,我想尝尝鲜. Pom中刚刚换了dependency马 ...

  6. python学习小结

    1学习的课程名字叫什么 python:前端初识html,后台基础flask 2怎么输出一句话,用代码举例 输出用:print 例如: 3使用终端工具怎么运行 Python代码 例如我要运行题目2的程序 ...

  7. Ubuntu终端命令行缩短显示路径

    平时我们使用linux终端命令行的时候,常常会被一个问题困扰,那就是文件路径过长, 有时候甚至超过了一行,这样看起来非常别扭,其实只要两步就可以解决这个问题: 1,修改.bashrc文件(用户根目录下 ...

  8. Pyhton学习——Day1

    1.什么是机器码?什么是字节码?机器码(machine code),学名机器语言指令,有时也被称为原生码(Native Code),是电脑的CPU可直接解读的数据. 通常意义上来理解的话,机器码就是计 ...

  9. python海龟的使用

    ############################螺旋正方形############################### import turtle turtle.left(90)for i ...

  10. spring boot-- 三种启动方式

    spring-boot的三种启动方式 1. 直接运行SpringbootApplication.java 2.在项目目录下运行mvn spring-boot:run 3.先编译项目mvn instal ...