zoukankan      html  css  js  c++  java
  • 【洛谷P1462】【二分+堆优化dij】

    题目描述

    在艾泽拉斯,有n个城市。编号为1,2,3,...,n。

    城市之间有m条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联盟的攻击,进而损失一定的血量。

    每次经过一个城市,都会被收取一定的过路费(包括起点和终点)。路上并没有收费站。

    假设1为暴风城,n为奥格瑞玛,而他的血量最多为b,出发时他的血量是满的。

    歪嘴哦不希望花很多钱,他想知道,在可以到达奥格瑞玛的情况下,他所经过的所有城市中最多的一次收取的费用的最小值是多少。

    题目分析

    题目说了那么多,其实就是让求在角色不死亡的情况下移动过程遇到的F[i]的最大值的最小值..【看到最大值的最小值就应该立马想到二分啊..然而蒟蒻终究是蒟蒻..没想到二分..而是无脑堆优化的使用dij..结果TLE到怀疑人生,看到别人的题解之后才想到用二分..orz..】

    题意这样就很明白了 二分是一定要用的 这种问法基本十个有九个是要用二分

    那么我们要二分什么呢 血量还是金钱呢

    因为要求的是收费所以就二分金钱好了////

    二分的条件就是 以当前值为最大值 ,不走大于二分值的点,然后用堆优化的dij判断是否连通就行了

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 #include<cstring>
     5 using namespace std;
     6 const int maxn1=10000;
     7 const int maxn2=50000;
     8 const int maxn3=1000000005;
     9 struct pot{
    10     int id;
    11     int rest;
    12      bool operator <(const struct pot&AA)const{
    13         return rest < AA.rest;
    14     }
    15 };
    16 struct edge{
    17     int next;
    18     int to;
    19     int len;
    20 }EDGE[maxn2*2+5];
    21 int dist[maxn1+5],head[maxn1+5],dist1[maxn1+5];
    22 int n,m,b;
    23 int edge_cnt=0;
    24 priority_queue<struct pot>pq;
    25 void add(int x,int y,int z)
    26 {
    27     EDGE[edge_cnt].to=y;
    28     EDGE[edge_cnt].next=head[x];
    29     EDGE[edge_cnt].len=z;
    30     head[x]=edge_cnt++;
    31 }
    32 int mmin=-1;
    33 bool dij(int x)
    34 {
    35     memset(dist1,0,sizeof(dist1));
    36     while(!pq.empty())
    37     {
    38         pq.pop();
    39     }
    40     pq.push((struct pot){1,b});
    41     while(!pq.empty())
    42     {
    43         struct pot aa=pq.top();pq.pop();
    44         if(aa.rest<dist1[aa.id])continue;
    45         for(int i = head[aa.id]; i != -1 ; i=EDGE[i].next)
    46         {
    47             int v=EDGE[i].to;
    48             if(dist[v]<=x&&aa.rest-EDGE[i].len>0)
    49             {
    50                 if(v==n){
    51                 return true;
    52             }
    53                 if(dist1[v]<aa.rest-EDGE[i].len)
    54                 {
    55                     dist1[v]=aa.rest-EDGE[i].len;
    56                     pq.push((struct pot){v,aa.rest-EDGE[i].len});
    57                 }
    58             }
    59         }
    60     }
    61     return false;
    62 }
    63 int main()
    64 {
    65     scanf("%d%d%d",&n,&m,&b);
    66     int r=0;    
    67     for(int i = 1 ; i <= n ; i++)
    68     {
    69         scanf("%d",&dist[i]);
    70         r=max(r,dist[i]);
    71     }
    72     memset(head,-1,sizeof(head));
    73     while(m--)
    74     {
    75         int q,w,e;
    76         scanf("%d%d%d",&q,&w,&e);
    77         add(q,w,e);
    78         add(w,q,e);
    79     }
    80     int l=max(dist[1],dist[n]);
    81     bool flag=false;
    82     while(l<=r)
    83     {
    84         int mid=(l+r)/2;
    85         if(dij(mid)){
    86             r=mid-1;
    87             flag=true;
    88         }
    89         else
    90         {
    91             l=mid+1;
    92          } 
    93     }
    94     if(!flag)
    95     printf("AFK
    ");
    96     else
    97     cout << l<< endl;
    98     return 0;
    99 }
    View Code

  • 相关阅读:
    【Java线程】Java内存模型总结
    转:【Java并发编程】之二十三:并发新特性—信号量Semaphore(含代码)
    转:【Java并发编程】之二十二:并发新特性—障碍器CyclicBarrier(含代码)
    【知识强化】第五章 输入/输出(I/O)管理 5.2 I/O核心子系统I
    【知识强化】第四章 文件管理 4.3 磁盘组织与管理
    【知识强化】第四章 文件管理 4.1+4.2 文件系统基础和实现
    【知识强化】第三章 内存管理 3.1 内存管理概念
    【知识强化】第二章 进程管理 2.4 死锁
    【知识强化】第二章 进程管理 2.3 进程同步
    LeetCode Unique Substrings in Wraparound String
  • 原文地址:https://www.cnblogs.com/MekakuCityActor/p/8989840.html
Copyright © 2011-2022 走看看