高玩小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. 【Azure Developer】Python代码通过AAD认证访问微软Azure密钥保管库(Azure Key Vault)中机密信息(Secret)

    关键字说明 什么是 Azure Active Directory?Azure Active Directory(Azure AD, AAD) 是 Microsoft 的基于云的标识和访问管理服务,可帮 ...

  2. /usr/local/mysql/bin/mysqlbinlog -vv /var/lib/bin/mysql-bin.000008 --base64-output=DECODE-ROWS --start-pos=307

    /usr/local/mysql/bin/mysqlbinlog -vv /var/lib/bin/mysql-bin.000008 --base64-output=DECODE-ROWS  --st ...

  3. C/C++内存对齐详解

    1.什么是内存对齐 还是用一个例子带出这个问题,看下面的小程序,理论上,32位系统下,int占4byte,char占一个byte,那么将它们放到一个结构体中应该占4+1=5byte:但是实际上,通过运 ...

  4. leetcode 1593. 拆分字符串使唯一子字符串的数目最大(DFS,剪枝)

    题目链接 leetcode 1593. 拆分字符串使唯一子字符串的数目最大 题意: 给你一个字符串 s ,请你拆分该字符串,并返回拆分后唯一子字符串的最大数目. 字符串 s 拆分后可以得到若干 非空子 ...

  5. CTFHub - Web(三)

    密码口令: 弱口令: 1.随意输入账号密码,抓包, 2.右击,"Send to Intruder",打开选项卡Intruder,点击position,椭圆框处软件已经自动为我们把要 ...

  6. Jmeter(三十六) - 从入门到精通进阶篇 - 设置负载阶梯式压测场景(详解教程)

    1.简介 在性能测试中,有时需要模拟一种实际生产中经常出现的情况,即:从某个值开始不断增加压力,直至达到某个值,然后持续运行一段时间,然后继续加压达到某个值持续运行,如此循环直到达到预期的峰值,运行一 ...

  7. ABAP 面试问题和答案

    What is an ABAP data dictionary?- ABAP 4 data dictionary describes the logical structures of the obj ...

  8. 判断最长回文串——暴力、延展、Manacher

    1. 暴力 时间复杂度O(n^3). 2. 延展 以某一字符为中心,设置left, right两个变量同时向外扩,判断他们指向字符是否相同.注意分奇偶讨论.时间复杂度O(n^2). 3. Manach ...

  9. Gradle使用及配置

    构建工具:Gradle(6.8) 下载地址:https://gradle.org/releases/ 下载最新版的二进制文件即可,下载"gradle-6.8.1-bin.zip文件,下载后完 ...

  10. tcpdump 参数详解及使用案例

    参数 -A 以ASCII码方式显示每一个数据包(不会显示数据包中链路层头部信息). 在抓取包含网页数据的数据包时, 可方便查看数据(nt: 即Handy for capturing web pages ...