HDU-6290 奢侈的旅行 (Dijkstra+堆优化)
这些城镇之间有mm条单向道路,第ii 条单项道路包含四个参数ui,vi,ai,biui,vi,ai,bi,表示一条从uiui号城镇出发,在vivi号城镇结束的单向道路,因为是单向道路,这不意味着小Q可以从vivi沿着该道路走到uiui。小Q的初始等级levellevel为11,每当试图经过一条道路时,需要支付cost=log2level+ailevelcost=log2level+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点需要花费的最小积分
题解:
思路参考链接: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+堆优化)的更多相关文章
- hdu 2544 单源最短路问题 dijkstra+堆优化模板
最短路 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- HDU-6290_奢侈的旅行(Dijstra+堆优化)
奢侈的旅行 Time Limit: 14000/7000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others) Problem De ...
- POJ 2502 - Subway Dijkstra堆优化试水
做这道题的动机就是想练习一下堆的应用,顺便补一下好久没看的图论算法. Dijkstra算法概述 //从0出发的单源最短路 dis[][] = {INF} ReadMap(dis); for i = 0 ...
- Bzoj 2834: 回家的路 dijkstra,堆优化,分层图,最短路
2834: 回家的路 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 62 Solved: 38[Submit][Status][Discuss] D ...
- 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 ...
- 深入理解dijkstra+堆优化
深入理解dijkstra+堆优化 其实就这几种代码几种结构,记住了完全就可以举一反三,所以多记多练多优化多思考. Dijkstra 对于一个有向图或无向图,所有边权为正(边用邻接矩阵的形式给出), ...
- dijkstra堆优化(multiset实现->大大减小代码量)
例题: Time Limit: 1 second Memory Limit: 128 MB [问题描述] 在电视时代,没有多少人观看戏剧表演.Malidinesia古董喜剧演员意识到这一事实,他们想宣 ...
- hdu3790 dijkstra+堆优化
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=3790 分析:dijkstra没有优化的话,复杂度是n*n,优化后的复杂度是m*logm,n是顶点数,m ...
- POJ 1511 - Invitation Cards 邻接表 Dijkstra堆优化
昨天的题太水了,堆优化跑的不爽,今天换了一个题,1000000个点,1000000条边= = 试一试邻接表 写的过程中遇到了一些问题,由于习惯于把数据结构封装在 struct 里,结果 int [10 ...
随机推荐
- #2020征文-开发板# 用鸿蒙开发AI应用(五)HDF 驱动补光灯
目录: 前言 硬件准备 HDF 驱动开发 总结 前言上一篇,我们在鸿蒙上运行了第一个程序,这一篇我们来编写一个驱动开启摄像头的红外补光灯,顺便熟悉一下鸿蒙上的 HDF 驱动开发. 硬件准备先查一下原理 ...
- 【System】paging和swaping之间的区别是什么?
分析paging和swapping的区别,首先要了解内存管理 当虚拟内存用二级存储(物理磁盘)作为主存的扩展时,内核会尽力保持最活跃的数据在主存中.有一下两个内核例程做这件事情: 1.交换(swapp ...
- 【Linux】用find删除大于30天的文件
1.删除文件命令: find 对应目录 -mtime +天数 -name "文件名" -exec rm -rf {} \; 实例命令:find /opt/soft/log/ -mt ...
- Puzzle (II) UVA - 519
题目链接: https://vjudge.net/problem/UVA-519 思路: 剪枝+回溯 这个题巧妙的是他按照表格的位置开始搜索,也就是说表格是定的,他不断用已有的图片从(0,0)开始拼到 ...
- mysql—make_set函数
使用格式:MAKE_SET(bits,str1,str2,-) 1 返回一个设定值(含子字符串分隔字符串","字符),在设置位的相应位的字符串.str1对应于位0,str2到第1位 ...
- Python编程小技巧(一)
在使用Tkinter编写代码的时候,有时候会忘记某个组件的参数是什么或者忘记某个参数怎么拼写的,此时可以通过如下方式查询组件的参数列表,以按钮组件为例: 1 # -*- coding:utf-8 -* ...
- 注解 @AutoConfigureBefore 和 @AutoConfigureAfter 的用途
注解 @AutoConfigureBefore 和 @AutoConfigureAfter 的用途 介绍: 如果你想将在SpringBoot项目中的配置类进行排序,那么用到spring-boot-au ...
- Vue基础之插值表达式的另一种用法!附加变量的监听!
Vue基础之插值表达式的另一种用法!附加变量的监听! 讲这个之前我们先回顾一下原来的用法! <body> <!-- Vue.js的应用可以分为两个重要的组成部分 一个是视图! 另一个 ...
- Mybatis总结(一)
Mybatis总结(一) 一.Mybatis启动流程(代码层面) 关于config.xml <?xml version="1.0" encoding="UTF-8& ...
- hive搜索报错
在自己搭建的集群上执行hive搜索语句 select count(*) from ods_event_log where dt='2019-12-14' group by dt; 报错如下: Stat ...