题目描述

小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. 在Mac OSX上安装ffmpeg && ffmpeg命令行将h264封装为mp4

    ffmpeg功能强大,可以通过命令行来对音视频进行处理.为了使用其功能,我在Mac上对其进行了安装. 我的Mac OS X 系统版本:OS X Yosemite, 10.10.14 关于ffmpeg在 ...

  2. DataTable和List相互转换的类

    DataTable与List相互转换 .NET后台数据处理,从数据库中的捞出的数据格式一般是List和DataTable的格式.现在将两种格式相互转换的心得记录下来以便以后查找(直接上代码). pub ...

  3. python ansible api

    #!/usr/bin/env python # -*- coding: utf-8 -*- # @File : test2.py # @Author: Anthony.waa # @Date : 20 ...

  4. JavaScript实现数字时钟功能

    <html> <head> <meta charset="utf-8"> <title>无标题文档</title> &l ...

  5. javascript中变量命名冲突的问题

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. SqlServer与MySql语法比较

    1.复制表(包括表结构.表数据) SqlServer: Select * into user_copy from user MySql: CREATE TABLE user_copy LIKE use ...

  7. 如何在CorelDRAW中创建对象阴影

    阴影工具可以为对象创建光线映射的阴影效果,使对象产生较强的立体感.可以为大多数对象或群组对象添加阴影,其中包括美术字.段落文本和位图.创建对象阴影可以增加视觉层次,使图形更加逼真. CorelDRAW ...

  8. javascript面向对象中继承实现的几种方式

    1.原型链继承: function teacher(name){ this.name = name; } teacher.prototype.sayName = function(){ alert(t ...

  9. 热重载 预编译 编译器 JS引擎 作用域

    热重载就是页面每次改动,不需要手动去刷新,可自动刷新.保持vuex的状态. JS之预编译 JavaScript的预编译 编译器 JS引擎 作用域三者之间的关系 建议你先去看看你不知道的JavaScri ...

  10. linux部署.net core api并且实现上传图片

    为了体验.net在linux上运行,所以使用HttpClient东借西抄做了一个简单的api上传功能. 第一步,简单的上传功能: public class UploadHelper { private ...