• SCU-4527 NightMare2(最短路+二分)


    思路就是二分枚举起点到达终点能携带的最多财宝数量,原本的spfa是在dis[v]>dis[u]+w时就松弛起点到v点距离,但是这里加了一个条件要携带值为mid的财宝,所以还要判断一下这条边是否可以携带mid财宝。还要注意题目没有说输入的u和v哪个是起点哪个是终点

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const ll inf =3e9;
    struct edge
    {
        int v,nxt;
        ll cap,w;
    
    }e[50000+10];
    int head[10000+10],vis[10000+10];
    ll dis[10000+10];
    int n,m;
    ll k;
    int tot;
    bool spfa(ll mid)
    {
        for(int i=1;i<=n;i++)
        {
            dis[i]=inf;
            vis[i]=0;
        }
        queue<int>q;
        while(!q.empty()) q.pop();
        dis[1]=0;
        vis[1]=1;
        q.push(1);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            vis[u]=0;
            for(int i=head[u];i!=-1;i=e[i].nxt)
            {
                int v=e[i].v;
                ll cap=e[i].cap;
                ll w=e[i].w;
                if((dis[v]>dis[u]+w)&&(cap>=mid)&&(dis[u]+w)<=k)
                {
                    dis[v]=dis[u]+w;
                    if(!vis[v])
                    {
                        vis[v]=1;
                        q.push(v);
                    }
                }
            }
        }
        return (dis[n]<=k);
    
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            tot=0;
            ll low=0,up=-1,mid,ans=-1;
            scanf("%d%d%lld",&n,&m,&k);
            for(int i=1;i<=n;i++) head[i]=-1;
            for(int i=0;i<m;i++)
            {
                int u,v;
                ll c,w;
                scanf("%d%d%lld%lld",&u,&v,&c,&w);
                e[tot].v=v;
                e[tot].cap=c;
                e[tot].w=w;
                e[tot].nxt=head[u];
                head[u]=tot++;
                e[tot].v=u;
                e[tot].cap=c;
                e[tot].w=w;
                e[tot].nxt=head[v];
                head[v]=tot++;
                up=max(up,c);
    
            }
            while(low<=up)
            {
                //cout<<mid<<endl;
    
                mid=(low+up)/2;
                if(spfa(mid))
                {
                    low=mid+1;
                    ans=mid;
    
                }
                else
                    up=mid-1;
            }
            //cout<<"low:"<<low<<"   up:"<<up<<endl;
            if(ans==-1)
                printf("Poor RunningPhoton!
    ");
            else
                printf("%lld
    ",ans);
    
    
    
        }
        return 0;
    }
    
  • 相关阅读:
    Java正则表达式匹配例子
    python实现的json数据以HTTP GET,POST,PUT,DELETE方式页面请求
    pure-Python PDF library
    搭建nginx反向代理用做内网域名转发
    ASCII、Unicode、UTF-8 字符串和编码
    pdftk
    SQL中distinct 和 row_number() over() 的区别及用法
    使用Python进行AES加密和解密
    python中zip()函数的用法
    查找只出现一次的字符和位置
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754995.html
Copyright © 2020-2023  润新知