zoukankan      html  css  js  c++  java
  • luogu P1462 通往奥格瑞玛的道路

    题目描述

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

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

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

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

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

    输入格式

    第一行3个正整数,n,m,b。分别表示有n个城市,m条公路,歪嘴哦的血量为b。

    接下来有n行,每行1个正整数,fi。表示经过城市i,需要交费fi元。

    再接下来有m行,每行3个正整数,ai,bi,ci(1<=ai,bi<=n)。表示城市ai和城市bi之间有一条公路,如果从城市ai到城市bi,或者从城市bi到城市ai,会损失ci的血量。

    输出格式

    仅一个整数,表示歪嘴哦交费最多的一次的最小值。

    如果他无法到达奥格瑞玛,输出AFK。


    让最大值最小,可以考虑二分答案。

    对于每次二分出的值mid,我们连接上边权小于等于mid的边,然后以血量为代价跑一遍最短路,如果最短路小于等于血量的话,那么这个mid就是合法的。

    时间复杂度为O((N+M)log(N+M)logAns)。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #define maxn 10001
    #define maxm 50001
    using namespace std;
    int n,m,c,val[maxn];
    long long b;
    inline int read(){
        register int x(0),f(1); register char c(getchar());
        while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
        while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    
    struct edge{
        int u,v,w;
    }e[maxm];
    vector<int> to[maxn],w[maxn];
    
    long long dis[maxn];
    int ans=-1;
    bool vis[maxn];
    priority_queue< pair<int,int>,vector< pair<int,int> >,greater< pair<int,int> > > q;
    inline bool dijkstra(){
        memset(dis,0x3f,sizeof dis),memset(vis,false,sizeof vis);
        q.push(make_pair(dis[1]=0,1));
        while(q.size()){
            int u=q.top().second; q.pop();
            if(vis[u]) continue; vis[u]=true;
            for(register int i=0;i<to[u].size();i++){
                int v=to[u][i];
                if(dis[v]>dis[u]+w[u][i]) dis[v]=dis[u]+w[u][i],q.push(make_pair(dis[v],v));
            }
        }
        return dis[n]<=b;
    }
    inline void binary(){
        int l=0,r=c,mid;
        while(l<=r){
            mid=l+r>>1;
            for(register int i=1;i<=n;i++) to[i].clear(),w[i].clear();
            for(register int i=1;i<=m;i++) if(val[e[i].u]<=mid&&val[e[i].v]<=mid){
                int u=e[i].u,v=e[i].v;
                to[u].push_back(v),w[u].push_back(e[i].w);
                to[v].push_back(u),w[v].push_back(e[i].w);
            }
            if(dijkstra()) ans=mid,r=mid-1;
            else l=mid+1;
        }
    }
    
    int main(){
        n=read(),m=read(),scanf("%lld",&b);
        for(register int i=1;i<=n;i++) val[i]=read(),c=max(c,val[i]);
        for(register int i=1;i<=m;i++) e[i].u=read(),e[i].v=read(),e[i].w=read();
        binary();
        if(ans==-1) puts("AFK");
        else printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    The Python Standard Library
    Python 中的round函数
    Python文件类型
    Python中import的用法
    Python Symbols 各种符号
    python 一行写多个语句
    免费SSL证书(https网站)申请,便宜SSL https证书申请
    元宇宙游戏Axie龙头axs分析
    OLE DB provider "SQLNCLI10" for linked server "x.x.x.x" returned message "No transaction is active.".
    The operation could not be performed because OLE DB provider "SQLNCLI10" for linked server "xxx.xxx.xxx.xxx" was unable to begin a distributed transaction.
  • 原文地址:https://www.cnblogs.com/akura/p/11066818.html
Copyright © 2011-2022 走看看