• 洛谷 P1462 通往奥格瑞玛的道路


    题目链接:https://www.luogu.org/problem/P1462

    思路:二分最大金钱数,最短路需要耗费的血量。

    直接二分最大金币数,无论该金币数是否出现在图上,通过二分的区间缩小即金币范围缩小,

    一定会得到一个图上存在的最小的最大金币数。

    最短路耗血量,只需要有一条能满足该最大金币数即可。


      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <queue>
      6 #include <stack>
      7 #include <set>
      8 #include <cmath>
      9 #include <string>
     10 #include <map>
     11 #include <cmath>
     12 #include <iomanip>
     13 using namespace std;
     14  
     15 typedef long long LL;
     16 #define inf 1e9
     17 #define rep(i,j,k) for(int i = (j); i <= (k); i++)
     18 #define rep__(i,j,k) for(int i = (j); i < (k); i++)
     19 #define per(i,j,k) for(int i = (j); i >= (k); i--)
     20 #define per__(i,j,k) for(int i = (j); i > (k); i--)
     21 
     22 const int N = (int)1e4 + 10;
     23 int head[N];
     24 int f[N];
     25 int cnt;
     26 bool vis[N];
     27 LL dis[N];
     28 int n,m,tx;
     29 int u,v,w;
     30 
     31 struct Edge{
     32     int to;
     33     int next;
     34     int w;
     35 }e[5 * N << 1];
     36 
     37 struct node{
     38     int loc;
     39     int w;
     40 
     41     bool friend operator<(const node& a,const node& b){
     42         return a.w > b.w;
     43     }
     44 };
     45 priority_queue<node > que;
     46 
     47 void add(int u,int v,int w){
     48     e[cnt].to = v;
     49     e[cnt].w = w;
     50     e[cnt].next = head[u];
     51     head[u] = cnt++;
     52 }
     53 
     54 LL dijkstra(LL mid){
     55 
     56     while(!que.empty()) que.pop();
     57     rep(i,1,n){
     58         vis[i] = false;
     59         dis[i] = inf;
     60     }
     61     dis[1] = 0;
     62     que.push(node{1,0});
     63 
     64     int u,v,w;
     65     while(!que.empty()){
     66         u = que.top().loc;
     67         que.pop();
     68         vis[u] = true;
     69 
     70         for(int o = head[u]; ~o; o = e[o].next){
     71             v = e[o].to;
     72             w = e[o].w;
     73 
     74             if(f[v] > mid) continue; //超出金币限度
     75 
     76             if(!vis[v] && dis[v] > dis[u] + w){
     77                 dis[v] = dis[u] + w;
     78                 que.push(node{v,dis[v]});
     79             }
     80         }
     81     }
     82 
     83     return dis[n];
     84 }
     85 
     86 int main(){
     87 
     88     scanf("%d%d%d",&n,&m,&tx);
     89     
     90     rep(i,1,n) head[i] = -1;
     91     cnt = 0;
     92     rep(i,1,n) scanf("%d",f + i);
     93     rep(i,1,m){
     94         scanf("%d%d%d",&u,&v,&w);
     95         add(u,v,w);
     96         add(v,u,w);
     97     }
     98 
     99     LL l = 1,r = (LL)1e9;
    100     LL mid;
    101     int ans = inf;
    102     bool ok = false;
    103     while(l <= r){
    104         mid = (l + r) >> 1;
    105         if(dijkstra(mid) > (LL)tx) l = mid + 1; //该mid金币不存在一条路
    106         else{//该mid金币存在一条路,继续二分答案
    107             ans = min(mid,(LL)ans); //记录可行的mid
    108             r = mid - 1;
    109             ok = true;
    110         }
    111     } 
    112     if(!ok) printf("AFK
    ");
    113     else printf("%d
    ",ans);
    114 
    115     getchar(); getchar();
    116     return 0;
    117 }
  • 相关阅读:
    深入V8引擎-Time核心方法之win篇(2)
    深入V8引擎-Time核心方法之win篇(1)
    深入V8引擎-Time核心方法之mac篇
    深入V8引擎-Time模块介绍
    深入V8引擎-写在前面
    深入V8引擎-编译启动
    【机器学习】极大似然估计法
    【机器学习】贝叶斯决策论
    【机器学习】贝叶斯决策 实例
    【机器学习】贝叶斯公式
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/11418091.html
Copyright © 2020-2023  润新知