ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

通往奥格瑞玛的道路——dijkstra+二分

2022-03-05 12:32:36  阅读:183  来源: 互联网

标签:二分 满足条件 瑞玛 idx int mid 奥格 dijkstra


P1462 通往奥格瑞玛的道路 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

 

一道将dijkstra和二分完美结合的一道题。

分析题意:

1.题中的“他所经过的所有城市中最多的一次收取的费用的最小值是多少”,太绕了。意思就是说这个人经过的所有城市中收费最大的那个城市的费用最少是多少。举个例子,假如这个人有两条满足条件的路可以走,第一条路收费最多的那个城市需要的费用是10块钱,第二条路收费最多的那个城市需要的费用是18块钱,那么答案就是10块钱。注意:题中这句话可以转化为求最大值的最小值,那么就是二分二分二分!所以我们求最后答案需要用二分解决。

 

2.题中有个必须要满足的条件,血量不能是负数,可以将血量当作dijkstra的dist距离,如果跑一遍图最后dist[n]大于总血量,那么说明这个人gg了,跑不到终点。

 

3.二分的判断条件是在单个城市最大收费是mid的情况下 是否能跑完整个图。

所以dijkstra是bool类型,并且在dijkstra中if判断血量(距离)的时候要同时判断这个城市的收费是否小于等于mid

 

收获:

真正明白了二分中if判断条件的意义,格局稍微打开了点,会将dijkstra与二分联系在一起了。并且明白了最大值的最小值这种关键句,是二分的意思。

 

代码实现:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 inline int read()
 4 {
 5     int sum=0;char a=getchar();
 6     while(a<'0'||a>'9')a=getchar();
 7     while(a>='0'&&a<='9')
 8     {
 9         sum=(sum<<3)+(sum<<1)+a-'0';
10         a=getchar();
11     }
12     return sum;
13 }
14 const int N=1e4+100,M=1e5+100,maxx=1e9+5;
15 int n,m,b,idx;
16 int f[N],dist[N],h[N];
17 bool st[N];
18 typedef pair<int,int> pii;
19 priority_queue<pii,vector<pii>,greater<pii> >q;
20 
21 struct EDG
22 {
23     int ne,to,w;
24 }e[M];
25 
26 void add(int x,int y,int v)
27 {
28     idx++;
29     e[idx].ne=h[x];e[idx].to=y;e[idx].w=v;h[x]=idx;
30 }
31 
32 bool dijkstra(int u)
33 {
34     if(u<f[1])return 0;    //如果费用u连1都进不去,那就没必要继续跑图了 
35     
36     
37     memset(dist,0x3f,sizeof dist);
38     memset(st,0,sizeof st);
39     dist[1]=0;
40     q.push({0,1});
41     
42     while(q.size())
43     {
44         pii sta=q.top();q.pop();
45         int x=sta.second,distance=sta.first;
46         if(st[x])continue;
47         st[x]=1;
48         
49         for(int i=h[x];i;i=e[i].ne)
50         {
51             int y=e[i].to;
52             if(dist[y]>distance+e[i].w&&f[y]<=u)//注意每个地点的费用都小于等于指定的费用     
53             {
54                 dist[y]=distance+e[i].w;
55                 if(!st[y])q.push({dist[y],y});
56             }
57         }
58     }
59     if(dist[n]<=b)return 1;    
60     //如果在每个地点的收费都小于等于u的情况下,能跑完全图就返回1 
61     else return 0;
62     
63 }
64 
65 
66 int main()
67 {
68     n=read();m=read();b=read();
69     for(int i=1;i<=n;i++)f[i]=read();
70     
71     for(int i=1;i<=m;i++)
72     {
73         int a,t,c;
74         a=read();t=read();c=read();
75         add(a,t,c);add(t,a,c);
76     }
77     
78     if(dijkstra(maxx)==0)    //在费用最大的时候仍然不能跑完全图,说明没戏了 
79     {
80         printf("AFK\n");
81         return 0;
82     }
83     
84     int l=1,r=maxx;
85     while(l<=r)
86     {
87         int mid=(l+r)>>1;
88         int c=dijkstra(mid);    
89         //用dijkstra判断,如果在单个收费最多为mid的时候能跑完全图就满足条件 
90         
91         if(c)r=mid-1;    //满足条件,就试一试如果最大值再小一点的情况 
92         else l=mid+1;    //不满足条件,就试试 最大值再大点的情况 
93     }
94     
95     printf("%d\n",l);
96     
97     
98     return 0;
99 }
View Code

 

标签:二分,满足条件,瑞玛,idx,int,mid,奥格,dijkstra
来源: https://www.cnblogs.com/wellerency/p/15967591.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有