• P1462 通往奥格瑞玛的道路


    最大的一次收费最小,不由联想到二分

    • 二分最大的一次收费mid,则要求从1走到n的路径上经过的点所收取的费用均不能超过mid
    • 为了判断当前取mid能否走到终点,采用贪心的思想,应该走从1到n的最短路径(路径上的权值表示伤害,初始血量为b),即伤害最小
    • 判断在伤害最小的路径上能否走到终点
    const int N=10010;
    vector<PII> g[N];
    int cost[N];
    int dist[N];
    bool vis[N];
    int n,m,b;
    
    bool check(int mid)
    {
        memset(dist,0x3f,sizeof dist);
        memset(vis,0,sizeof vis);
        priority_queue<PII,vector<PII>,greater<PII> > heap;
        dist[1]=0;
        heap.push({0,1});
    
        while(heap.size())
        {
            int t=heap.top().se;
            heap.pop();
    
            if(vis[t]) continue;
            vis[t]=true;
    
            for(int i=0;i<g[t].size();i++)
            {
                int j=g[t][i].fi,w=g[t][i].se;
                if(cost[j]<=mid && dist[j]>dist[t]+w)
                {
                    dist[j]=dist[t]+w;
                    heap.push({dist[j],j});
                }
            }
        }
    
        return dist[n]<=b;
    }
    
    int main()
    {
        cin>>n>>m>>b;
    
        for(int i=1;i<=n;i++) cin>>cost[i];
    
        int l=*min_element(cost+1,cost+n+1);
        int r=*max_element(cost+1,cost+n+1);
    
        while(m--)
        {
            int a,b,c;
            cin>>a>>b>>c;
            g[a].push_back({b,c});
            g[b].push_back({a,c});
        }
    
        if(!check(INF))
        {
            puts("AFK");
            return 0;
        }
    
        while(l<r)
        {
            int mid=l+r>>1;
            if(check(mid)) r=mid;
            else l=mid+1;
        }
    
        cout<<l<<endl;
    
        //system("pause");
    }
    
  • 相关阅读:
    什么叫开漏输出
    PIC16F877A TIMER1计数操作
    [转载]【Alientek STM32 实验2】按键输入
    STM32学习笔记1 IO口学习
    时间“四象限”法
    CLANNAD AFTER STORY 片头曲 「铭刻时间的歌」
    正则表达式测试工具
    War3窗口限定小工具发布
    利用ffmpeg转换mp4文件
    一个类似FlashGet的c#开源下载工具
  • 原文地址:https://www.cnblogs.com/fxh0707/p/13628396.html
Copyright © 2020-2023  润新知