zoukankan      html  css  js  c++  java
  • [LuoguP1462]通往奥格瑞玛的道路

    题目链接

    题意简述:现在有一个图,每经过一个点就会交钱,走一条路就会扣血。在血量>0的前提下,要从1走到n点,并且要求路径上交钱的最大值最小。

    解题思路:首先最大值最小,我们选择二分。目前有两个限制条件,血量与金钱。我们选择二分金钱,因为二分金钱就可以将一部分的城市排除在外,但二分血量不行(扣血是累加的,而金钱只是单个点,所以删点比删边更好了)。那么二分了金钱之后限制了部分城市不能走,二分对应的check就用dijistra,跑一遍可以去的城市中的最短路(路上扣血作为边权),此时我们可以求得扣血最少,再与总血量进行比较,比总血量少就是一个可行解,继续二分看一看是否有更优的答案。 至于没有解则是不对城市进行限制都无法活着回去。

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<fstream>
    #include<queue>
    using namespace std;
    int read(){
        int res=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            res=res*10+(ch-'0');
            ch=getchar();
        }
        return res*f;
    }
    const int MAXN=100005;
    int n,m,b,f[MAXN],head[MAXN],ne[MAXN],to[MAXN];
    int c[MAXN],tot,money,vis[MAXN],ans;
    priority_queue <pair<int,int> > q;
    long long d[MAXN];
    void add(int x,int y,int u){
        to[++tot]=y;
        c[tot]=u;
        ne[tot]=head[x];
        head[x]=tot;
    }
    bool dijistra(int max_money){
        memset(d,127/3,sizeof(d));
        memset(vis,0,sizeof(vis));
        d[1]=0;vis[1]=1;
        q.push(make_pair(0,1));
        while(!q.empty()){
            int u=q.top().second;
            q.pop();
            //vis[u]=0;
            for(int i=head[u];i;i=ne[i]){
                int v=to[i];
                if(f[v]>max_money||f[u]>max_money)continue;
                if(d[v]>d[u]+c[i]){
                    d[v]=d[u]+c[i];
                    if(!vis[v]){
                        vis[v]=1;
                        q.push(make_pair(-d[v],v));
                    }
                }
            }
        }
        if(d[n]<b)return 1;
        else return 0;
    }
    int main(){
        //freopen(".in","r",stdin);
        //freopen(".out","w",stdout);
        n=read();m=read();b=read();
        int l,r;
        for(int i=1;i<=n;++i){
            f[i]=read();
            r=max(f[i],r);
        }
        l=0;
        int a,b,c;
        for(int i=1;i<=m;++i){
            a=read();b=read();c=read();
            add(a,b,c);
            add(b,a,c);
        }
        if(!dijistra(1<<30)){
            printf("AFK");
            return 0;
        }
        r++;
        while(l<r){
            int mid=(l+r)>>1;
            if(dijistra(mid)){
                r=mid;
            }
            else {
                l=mid+1;
            }
        }
        printf("%d",l);
        return 0;
    }
    View Code
  • 相关阅读:
    大魔头视频解析 线路收集(持续更新)
    如何配置双网?
    pom配置资源文件中的二进制文件乱码打不开如excel
    漏洞复现-CVE-2017-7525-Jackson远程代码执行
    漏洞复现-CVE-2018-1000861-jenkins远程命令执行
    漏洞复现-wooyun-2015-110216-Elasticsearch写入webshell
    漏洞复现-CVE-2015-5531-ElasticSearch 目录穿越
    漏洞复现-nginx_parsing_vulnerability-nginx解析漏洞
    漏洞复现-insecure-configuration-nginx不安全的配置
    漏洞复现-CVE-2018-1273-Spring Data Commons 远程命令执行
  • 原文地址:https://www.cnblogs.com/clockwhite/p/11825294.html
Copyright © 2011-2022 走看看