洛谷 1462 通往奥格瑞玛的道路 题解

博客观赏效果更佳

题意简述

n n 个点 m m 条边的无向图,点边均有权。给定 b b 。请你找到一个从1到n的路使得边权和<=b且点权的最大值最小。

思路

二分+最短路。对于一个mid,把所有点权<=mid的点之间连边,跑最短路,看是否<=b即珂。

代码

#include <bits/stdc++.h>
using namespace std;
namespace Flandre_Scarlet
{
    #define N 155555
    #define int long long 
    #define F(i,l,r) for(int i=l;i<=r;++i)
    #define D(i,r,l) for(int i=r;i>=l;--i)
    #define Fs(i,l,r,c) for(int i=l;i<=r;c)
    #define Ds(i,r,l,c) for(int i=r;i>=l;c)
    #define Tra(G,i,u) for(int i=G.Start(u),__v=G.To(i);~i;i=G.Next(i),__v=G.To(i))
    #define MEM(x,a) memset(x,a,sizeof(x))
    #define FK(x) MEM(x,0)
    class Graph
    {
        public:
            int head[N];
            int EdgeCount;
            struct Edge
            {
                int To,Label,Next;
            }Ed[N<<1];
            void clear(int _V=N,int _E=N<<1) 
            {
                memset(Ed,-1,sizeof(Edge)*(_E));
                memset(head,-1,sizeof(int)*(_V));
                EdgeCount=-1;
            }
            void AddEdge(int u,int v,int w=1)
            {
                Ed[++EdgeCount]=(Edge){v,w,head[u]};
                head[u]=EdgeCount;
            }
            void Add2(int u,int v,int w=1) {AddEdge(u,v,w);AddEdge(v,u,w);}
            int Start(int u) {return head[u];}
            int To(int u){return Ed[u].To;}
            int Label(int u){return Ed[u].Label;}
            int Next(int u){return Ed[u].Next;}
    }G,Tmp;
    
    void R1(int &x)
    {
        x=0;char c=getchar();int f=1;
        while(c<'0' or c>'9') f=(c=='-')?-1:1,c=getchar();
        while(c>='0' and c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        x=(f==1)?x:-x;
    }
    int n,m,b;
    int val[N];
    void Input()
    {
        R1(n),R1(m),R1(b);
        F(i,1,n) R1(val[i]);
        Tmp.clear();
        F(i,1,m)
        {
            int u,v,w;R1(u),R1(v),R1(w);
            Tmp.Add2(u,v,w);
        } 
    }

    struct node{int v,w;};bool operator<(node a,node b){return a.w>b.w;}
    priority_queue<node> Q;
    int dis[N],vis[N];
    void Dijkstra()
    {
        while(!Q.empty()) Q.pop();
        MEM(dis,0x3f);FK(vis);
        Q.push((node){1,0});dis[1]=0;
        while(!Q.empty())
        {
            node Min=Q.top();Q.pop();
            int u=Min.v;
            if (vis[u]) continue;
            vis[u]=1;
            Tra(G,i,u)
            {int v=__v;
                if (!vis[v] and dis[v]>dis[u]+G.Label(i))
                {
                    dis[v]=dis[u]+G.Label(i);
                    Q.push((node){v,dis[v]});
                }
            }
        }
    }
    bool cxk(int mid)
    {
        G.clear();
        F(u,1,n) Tra(Tmp,i,u)
        {int v=__v;
            if (val[u]<=mid and val[v]<=mid)
            {
                G.Add2(u,v,Tmp.Label(i));
            }
        }
        Dijkstra();
        return dis[n]<=b;
    }
    void Soviet()
    {
        if (!cxk(1e18))
        {
            puts("AFK");return;
        }
        int l=0,r=1e15;
        while(l<r)
        {
            int mid=(l+r)>>1;
            if (cxk(mid)) r=mid;
            else l=mid+1;
        }
        printf("%lld\n",l);
    }

    #define Flan void
    Flan IsMyWife()
    {
        Input();
        Soviet();
    }
    #undef int //long long 
}
int main()
{
    Flandre_Scarlet::IsMyWife();
    getchar();getchar();
    return 0;
}
发布了210 篇原创文章 · 获赞 8 · 访问量 8988

猜你喜欢

转载自blog.csdn.net/LightningUZ/article/details/103338685