洛谷 P1462 通往奥格瑞玛的道路(二分答案,堆优化dijkstra)

传送门


解题思路

首先看题目问题,求经过的所有城市中最多的一次收取的费用的最小值是多少。一看“最大值最小”就想到了二分答案。

在读一遍题目,就是二分收取的费用,然后对于每一个二分的费用,跑一边最短路,要求不经过>收取费用的城市,最后看一看能否在规定血量内走到终点。

想起来还是比较容易的,写起来要注意一下细节,注意二分的形式和用堆优化的dijkstra的写法。

悲惨的做题经历

 

今天凌晨,终于灵光一现,发现了问题——变量定义在主函数外面时不能直接用另一个变量来赋初值!!怪不得总是wrong answer!!

终于解决了烦了我三天的题了(终于可以睡觉了)QAQ

AC代码

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<queue>
 7 using namespace std;
 8 const int maxn=10005;
 9 const int maxm=100005; 
10 long long n,m,b,f[maxn],p[maxn],cnt,d[maxn],vis[maxn],dis[maxn];
11 struct edge{
12     int v,next;
13     long long value;
14 }e[maxm];
15 void insert(int u,int v,long long value){
16     cnt++;
17     e[cnt].v=v;
18     e[cnt].next=p[u];
19     e[cnt].value=value;
20     p[u]=cnt;
21 }
22 struct node{
23     int num;
24     long long value;
25 };
26 bool operator <(node a,node b){
27     return a.value>b.value;
28 }
29 bool dijkstra(long long mid){
30     if(f[1]>mid||f[n]>mid) return false;
31     memset(dis,0x3f,sizeof(dis));
32     memset(vis,0,sizeof(vis));
33     priority_queue<node> q;
34     node tou;
35     tou.num=1;
36     tou.value=0;
37     dis[1]=0;
38     q.push(tou);
39     while(!q.empty()){
40         node u=q.top();
41         q.pop();
42         if(vis[u.num]) continue;
43         vis[u.num]=1;
44         for(long long i=p[u.num];i!=-1;i=e[i].next){
45             if(f[e[i].v]>mid) continue;
46             if(dis[u.num]+e[i].value<dis[e[i].v]){
47                 dis[e[i].v]=dis[u.num]+e[i].value;
48                 node neww;
49                 neww.num=e[i].v;
50                 neww.value=dis[e[i].v];
51                 if(!vis[e[i].v])q.push(neww);
52             }
53         }
54     }
55     if(dis[n]>=b) return false;
56     return true;
57 }
58 long long l=1,r;
59 int main()
60 {
61     cin>>n>>m>>b;
62     r=n;
63     memset(p,-1,sizeof(p));
64     for(int i=1;i<=n;i++){
65         scanf("%lld",&f[i]);
66         d[i]=f[i];
67     }
68     for(int i=1;i<=m;i++){
69         long long u,v,value;
70         scanf("%lld%lld%lld",&u,&v,&value);
71         insert(u,v,value);
72         insert(v,u,value);
73     }
74     sort(d+1,d+1+n);
75     if(!dijkstra(d[n])){
76         cout<<"AFK";
77         return 0;
78     } 
79     while(l<r){
80         int mid=(l+r)/2;
81         if(dijkstra(d[mid])) r=mid;
82         else l=mid+1;
83     }
84     cout<<d[l];
85     return 0;
86 }
原文地址:https://www.cnblogs.com/yinyuqin/p/11629109.html