高玩小Q不仅喜欢玩寻宝游戏,还喜欢一款升级养成类游戏。在这个游戏的世界地图中一共有nn个城镇,编号依次为11到nn。

这些城镇之间有mm条单向道路,第ii 条单项道路包含四个参数ui,vi,ai,biui,vi,ai,bi,表示一条从uiui号城镇出发,在vivi号城镇结束的单向道路,因为是单向道路,这不意味着小Q可以从vivi沿着该道路走到uiui。小Q的初始等级levellevel为11,每当试图经过一条道路时,需要支付cost=log2level+ailevelcost=log2⁡level+ailevel点积分,并且经过该道路后,小Q的等级会提升aiai级,到达level+ailevel+ai级。但是每条道路都会在一定意义上歧视低消费玩家,准确地说,如果该次所需积分cost<bicost<bi,那么小Q不能经过该次道路,也不能提升相应的等级。

注意:本游戏中等级为正整数,但是积分可以是任意实数。

小Q位于11号城镇,等级为11,现在为了做任务要到nn号城镇去。这将会是一次奢侈的旅行,请写一个程序帮助小Q找到需要支付的总积分最少的一条路线,或判断这是不可能的。

Input第一行包含一个正整数T(1≤T≤30)T(1≤T≤30),表示测试数据的组数。

每组数据第一行包含两个整数n,m(2≤n≤100000,1≤m≤200000)n,m(2≤n≤100000,1≤m≤200000),表示城镇数和道路数。

接下来mm行,每行四个整数ui,vi,ai,bi(1≤ui,vi≤n,ui≠vi,0≤ai≤109,0≤bi≤60)ui,vi,ai,bi(1≤ui,vi≤n,ui≠vi,0≤ai≤109,0≤bi≤60),分别表示每条单向道路。Output对于每组数据,输出一行一个整数,即最少所需的总积分的整数部分,如:4.99994.9999输出44,1.01.0输出11。若不存在合法路线请输出−1−1。Sample Input

1
3 3
1 2 3 2
2 3 1 6
1 3 5 0

Sample Output

2

题意:

给你n个点,m条边,每条边有u,v,a,b这四个值,初始等级为1.问你从1点到n点需要花费的最小积分

题解:

每次走过一条路i 的消费是 log2(( level i +ai)/(level i) )  式子可以转化为log2( ai  +  level i) - log2( level i),所以每次的消费就是log2( ai  +  level i) - log2( level i),如果走两条路,从1到v1再到v2 :那么消费就是
 log2(a1+ level1) - log2( level 1)+log2(a2+ level2)-log2(level2), 因为level2就是level1+a1,所以可以化简为- log2( level 1)+log2(a2+ level2),如果把这个式子扩长,可以发现中间的部分都可以通过一加一减化掉,只剩下-log2(1)+log2(level n) 因为log2(1)==0 所以只要求得到n时的最小等级leveln,对其求log2(level n)就是结果最小等级就可以直接用Dijkstra求最短路求得

思路参考链接:https://blog.csdn.net/chimchim04/java/article/details/90068314
 
 

我的出错点1:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<math.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=2e5+5;
typedef long long ll;
const ll MAX=1e17;
const ll inf=(ll)1<<61;
struct shudui1
{
ll start,value;
bool operator < (const shudui1 q)const
{
return value>q.value; //最短路模板中这里应该是大于号,我写成了小于号
}
} str1;

下面代码就是这个原因错的:

  1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 #include<algorithm>
5 #include<queue>
6 #include<vector>
7 #include<math.h>
8 using namespace std;
9 const int INF=0x3f3f3f3f;
10 const int maxn=2e5+5;
11 typedef long long ll;
12 const ll MAX=1e17;
13 const ll inf=(ll)1<<61;
14 struct shudui1
15 {
16 ll start,value;
17 bool operator < (const shudui1 q)const
18 {
19 return value<q.value;
20 }
21 } str1;
22 struct node
23 {
24 ll a,v,nex,b;
25 } e[maxn];
26 ll tot,v[maxn],p[70],vis[maxn],head[maxn];
27 void add(ll u,ll v,ll a,ll b)
28 {
29 e[tot].v=v,e[tot].a=a,e[tot].b=b;
30 e[tot].nex=head[u];
31 head[u]=tot++;
32 //printf("%d %d\n",tot-1,v);
33 }
34 priority_queue<shudui1>r; //里面的数据默认是从小到大排序,这样就不用通过for循环遍历在每一次找v里面的最小值,可以直接找到最小值,减少代码运行次数
35 void JK(ll s)
36 {
37 v[s]=1;
38 str1.start=s;
39 str1.value=1;
40 r.push(str1);
41 while(!r.empty())
42 {
43
44 ll x,y;
45 str1=r.top();
46 r.pop();
47 x=str1.start;
48 y=str1.value;
49 //printf("%lld***\n",x);
50 if(vis[x]) continue;
51 vis[x]=1;
52 //printf("**%lld\n",len);
53 for(ll i=head[x]; i!=-1; i=e[i].nex)
54 {
55
56 ll vv=e[i].v,a=e[i].a,b=e[i].b;
57 ll temp=1+a/v[x];
58 //printf("%lld %lld\n",temp,p[b]);
59 if(temp<p[b]) continue;
60 //printf("%lld %lld\n",v[x]+v,v[vv]);
61 if((v[x]+a<v[vv]))
62 {
63 //printf("**");
64 v[vv]=v[x]+a;
65 str1.start=vv;
66 str1.value=v[vv];
67 r.push(str1);
68 }
69 }
70 }
71 }
72 int main()
73 {
74 // double xx=1.99;
75 // printf("%.0lf\n",xx);
76 ll t;
77 p[0]=1;
78 for(ll i=1; i<=60; ++i)
79 p[i]=(ll)p[i-1]*(ll)2;
80 scanf("%lld",&t);
81 while(t--)
82 {
83 memset(head,-1,sizeof(head));
84 tot=0;
85 ll n,m;
86 scanf("%lld%lld",&n,&m);
87 for(ll i=1; i<=n; ++i)
88 v[i]=inf,vis[i]=0;
89 while(m--)
90 {
91 ll x,y,z1,z2;
92 scanf("%lld%lld%lld%lld",&x,&y,&z1,&z2);
93 add(x,y,z1,z2);
94 }
95 JK(1);
96 if(v[n]>=inf) printf("-1\n");
97 else
98 {
99 double x=log2(v[n]);
100 printf("%lld\n",(ll)x);
101 }
102 }
103 return 0;
104 }

出错点2:

while(!r.empty())
{ ll x,y;
str1=r.top();
r.pop();
x=str1.start;
y=str1.value;
//printf("%lld***\n",x);
if(vis[x]) continue;
vis[x]=1;
//printf("**%lld\n",len);
for(ll i=head[x]; i!=-1; i=e[i].nex)
{ ll vv=e[i].v,a=e[i].a,b=e[i].b;
ll temp=1+a/v[x]; //最短路算法里面这里应该是除于v[x],我却写成了str1.value
//printf("%lld %lld\n",temp,p[b]);
if(temp<p[b]) continue;
//printf("%lld %lld\n",v[x]+v,v[vv]);
if((v[x]+a<v[vv]))
{
//printf("**");
v[vv]=v[x]+a;
str1.start=vv;
str1.value=v[vv];
r.push(str1);
}
}
}

原代码:

  1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 #include<algorithm>
5 #include<queue>
6 #include<vector>
7 #include<math.h>
8 using namespace std;
9 const int INF=0x3f3f3f3f;
10 const int maxn=2e5+5;
11 typedef long long ll;
12 const ll MAX=1e17;
13 const ll inf=(ll)1<<61;
14 struct shudui1
15 {
16 ll start,value;
17 bool operator < (const shudui1 q)const
18 {
19 return value>q.value; //这里是大于号
20 }
21 } str1;
22 struct node
23 {
24 ll a,v,nex,b;
25 } e[maxn];
26 ll tot,v[maxn],p[70],vis[maxn],head[maxn];
27 void add(ll u,ll v,ll a,ll b)
28 {
29 e[tot].v=v,e[tot].a=a,e[tot].b=b;
30 e[tot].nex=head[u];
31 head[u]=tot++;
32 //printf("%d %d\n",tot-1,v);
33 }
34 priority_queue<shudui1>r; //里面的数据默认是从小到大排序,这样就不用通过for循环遍历在每一次找v里面的最小值,可以直接找到最小值,减少代码运行次数
35 void JK(ll s)
36 {
37 v[s]=1;
38 str1.start=s;
39 str1.value=1;
40 r.push(str1);
41 while(!r.empty())
42 {
43
44 ll x,y;
45 str1=r.top();
46 r.pop();
47 x=str1.start;
48 y=str1.value;
49 //printf("%lld***\n",x);
50 if(vis[x]) continue;
51 vis[x]=1;
52 //printf("**%lld\n",len);
53 for(ll i=head[x]; i!=-1; i=e[i].nex)
54 {
55
56 ll vv=e[i].v,a=e[i].a,b=e[i].b;
57 ll temp=1+a/v[x];//最短路算法里面这里应该是除于v[x],我却写成了str1.value
58 //printf("%lld %lld\n",temp,p[b]);
59 if(temp<p[b]) continue;
60 //printf("%lld %lld\n",v[x]+v,v[vv]);
61 if((v[x]+a<v[vv]))
62 {
63 //printf("**");
64 v[vv]=v[x]+a;
65 str1.start=vv;
66 str1.value=v[vv];
67 r.push(str1);
68 }
69 }
70 }
71 }
72 int main()
73 {
74 // double xx=1.99;
75 // printf("%.0lf\n",xx);
76 ll t;
77 p[0]=1;
78 for(ll i=1; i<=60; ++i)
79 p[i]=(ll)p[i-1]*(ll)2;
80 scanf("%lld",&t);
81 while(t--)
82 {
83 memset(head,-1,sizeof(head));
84 tot=0;
85 ll n,m;
86 scanf("%lld%lld",&n,&m);
87 for(ll i=1; i<=n; ++i)
88 v[i]=inf,vis[i]=0;
89 while(m--)
90 {
91 ll x,y,z1,z2;
92 scanf("%lld%lld%lld%lld",&x,&y,&z1,&z2);
93 add(x,y,z1,z2);
94 }
95 JK(1);
96 if(v[n]>=inf) printf("-1\n");
97 else
98 {
99 double x=log2(v[n]);
100 printf("%lld\n",(ll)x);
101 }
102 }
103 return 0;
104 }

整理之后的代码:

 1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 #include<algorithm>
5 #include<queue>
6 #include<vector>
7 #include<math.h>
8 using namespace std;
9 const int INF=0x3f3f3f3f;
10 const int maxn=2e5+5;
11 typedef long long ll;
12 const ll MAX=1e17;
13 const ll inf=(ll)1<<61;
14 struct shudui1
15 {
16 ll v,c;
17 shudui1(ll x=0,ll y=0):v(x),c(y) {}
18 bool operator < (const shudui1 q)const
19 {
20 return c>q.c;
21 }
22 } str1;
23 struct node
24 {
25 ll a,v,nex,b;
26 } e[maxn];
27 ll tot,dis[maxn],p[70],vis[maxn],head[maxn];
28 void add(ll u,ll v,ll a,ll b)
29 {
30 e[tot].v=v,e[tot].a=a,e[tot].b=b;
31 e[tot].nex=head[u];
32 head[u]=tot++;
33 //printf("%d %d\n",tot-1,v);
34 }
35 priority_queue<shudui1>r; //里面的数据默认是从小到大排序,这样就不用通过for循环遍历在每一次找v里面的最小值,可以直接找到最小值,减少代码运行次数
36 void JK(ll s,ll n)
37 {
38
39 dis[s]=1;
40 str1.v=s;
41 str1.c=1;
42 r.push(str1);
43 while(!r.empty())
44 {
45 str1=r.top();
46 r.pop();
47 int u=str1.v;
48 if(vis[u]) continue;
49 vis[u]=1;
50 //printf("%d %lld\n",u,dis[u]);
51 for(int i=head[u]; i!=-1; i=e[i].nex)
52 {
53 int v=e[i].v;
54 //printf(" %d\n",v);
55 ll a=e[i].a,b=p[e[i].b];
56 if(a/dis[u]+1<b) continue;
57 if(dis[v]>a+dis[u])
58 {
59 dis[v]=a+dis[u];
60 r.push(shudui1(v,dis[v]));
61 }
62 }
63 }
64 if(dis[n]>=inf) printf("-1\n");
65 else
66 {
67 double x=log2(dis[n]);
68 printf("%d\n",(int)x);
69 }
70 }
71 int main()
72 {
73 ll n,m;
74 p[0]=1;
75 for(ll i=1; i<=60; i++)
76 p[i]=(ll)p[i-1]*(ll)2;
77 ll t;
78 scanf("%lld",&t);
79 while(t--)
80 {
81 tot=0;
82 scanf("%lld%lld",&n,&m);
83 for(ll i=0; i<=n; i++)
84 {
85 vis[i]=0;
86 dis[i]=inf;
87 }
88 memset(head,-1,sizeof(head));
89 ll x,y,b,a;
90 for(ll i=0; i<m; i++)
91 {
92 scanf("%lld %lld %lld %lld",&x,&y,&a,&b);
93 add(x,y,a,b);
94 }
95 JK(1,n);
96 }
97 return 0;
98 }

HDU-6290 奢侈的旅行 (Dijkstra+堆优化)的更多相关文章

  1. hdu 2544 单源最短路问题 dijkstra+堆优化模板

    最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  2. HDU-6290_奢侈的旅行(Dijstra+堆优化)

    奢侈的旅行 Time Limit: 14000/7000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others) Problem De ...

  3. POJ 2502 - Subway Dijkstra堆优化试水

    做这道题的动机就是想练习一下堆的应用,顺便补一下好久没看的图论算法. Dijkstra算法概述 //从0出发的单源最短路 dis[][] = {INF} ReadMap(dis); for i = 0 ...

  4. Bzoj 2834: 回家的路 dijkstra,堆优化,分层图,最短路

    2834: 回家的路 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 62  Solved: 38[Submit][Status][Discuss] D ...

  5. POJ2387(dijkstra堆优化)

    Til the Cows Come Home Bessie is out in the field and wants to get back to the barn to get as much s ...

  6. 深入理解dijkstra+堆优化

    深入理解dijkstra+堆优化 其实就这几种代码几种结构,记住了完全就可以举一反三,所以多记多练多优化多思考. Dijkstra   对于一个有向图或无向图,所有边权为正(边用邻接矩阵的形式给出), ...

  7. dijkstra堆优化(multiset实现->大大减小代码量)

    例题: Time Limit: 1 second Memory Limit: 128 MB [问题描述] 在电视时代,没有多少人观看戏剧表演.Malidinesia古董喜剧演员意识到这一事实,他们想宣 ...

  8. hdu3790 dijkstra+堆优化

    题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=3790 分析:dijkstra没有优化的话,复杂度是n*n,优化后的复杂度是m*logm,n是顶点数,m ...

  9. POJ 1511 - Invitation Cards 邻接表 Dijkstra堆优化

    昨天的题太水了,堆优化跑的不爽,今天换了一个题,1000000个点,1000000条边= = 试一试邻接表 写的过程中遇到了一些问题,由于习惯于把数据结构封装在 struct 里,结果 int [10 ...

随机推荐

  1. mac配置Android SDK

    下载地址:http://tools.android-studio.org/index.php/sdk 2.找到tools文件夹 选中android-sdk-macosx包下的tools文件夹,按com ...

  2. Python基础语法4-运算符

    Python提供了一系列丰富的运算符,包括:  Ø算术运算符  Ø赋值运算符  Ø关系运算符  Ø逻辑运算符 Ø位运算符  Ø三元运算符 Ø身份运算符 Ø成员运算符

  3. 改进你的c#代码的5个技巧(四)

    像每一篇文章一样,我会重复几行.我在我的Core i3 CPU.4GB主内存和Windows 7平台上测试了以下代码.如果你在不同的硬件配置或使用不同的平台,那么你的输出可能会随着我的输出屏幕而变化, ...

  4. 绝对定位上下左右都为0 margin为auto为什么能居中

    老规矩,先来一段废话,我大学刚入门的时候觉得CSS很简单,记一记就会了,不就是盒模型嘛,现在想来觉得自己那时候真的很自以为是哈哈.但是随着工作沉淀,我明白了任何技术都有着它的深度和广度,正是因为不少人 ...

  5. 使用Azure Runbook 发送消息到Azure Storage Queue

    客户需要定时发送信息到Azure Storage Queue,所以尝试使用Azure Runbook实现这个需求. 首先新增一个Azure Automation Account的资源. 因为要使用Az ...

  6. 日志采集技术分析 Inode Inotify

    日志采集技术分析[阿里] - 新手学习导向 - 中国红客联盟 - Powered by HUC http://www.cnhonkerarmy.com/thread-236973-1-1.html

  7. 容器调度 • Docker网络 • 持续交付 • 动态运行应用程序 部署的多元化

    <英雄联盟>在线服务运维之道 - InfoQ https://www.infoq.cn/article/running-online-services-riot/ 第一章 简 介 我是Jo ...

  8. 网络优化之net.ipv4.tcp_tw_recycle和tcp_tw_reuse参数

    网络优化之net.ipv4.tcp_tw_recycle和tcp_tw_reuse参数 - 一个人默默潜行 - 博客园 https://www.cnblogs.com/ppp1314520818/p/ ...

  9. 结合python版本安装python-devel gcc和g++的区别 安装前做yum搜索

    [test@ecs autocloudservices]# yum install python-develLoaded plugins: fastestmirrorLoading mirror sp ...

  10. v-modal的使用。

    v-model用于表单数据的双向绑定,其实它就是一个语法糖,这个背后就做了两个操作:v-bind绑定一个value属性:v-on指令给当前元素绑定input事件.