其他分享
首页 > 其他分享> > luogu#P1462 通往奥格瑞玛的道路

luogu#P1462 通往奥格瑞玛的道路

作者:互联网

题意:

给出一张有 \(n\) 个点, \(m\) 条边的无向图

每个点上有一个点权 \(f[i]\) ,表示经过这个点需要交 \(f[i]\) 的费用。,每条边上有一个边权 \(C[i]\) ,表示经过这条边需要扣除 \(C[i]\) 的血量

求能从起点 \(1\) 到达 \(n\) 的情况下交费最多一次的最小值

解法:

先判断一次假设血量为最大血量+ 时是否可以走通

然后二分每次交的最大费用 \(w\) ,用dijkstra求从源点到终点需要的最小血量

==数据比较大需要开long long==

#include<iostream>
#include<queue>
#include<cstring>
#define ll long long
#define M 50005
#define N 10005
using namespace std;
struct Edge{ll next,to,dis;}edge[M<<1];

struct node{ll dis,u;bool operator < (const node &x)const {return x.dis<dis;}};

ll n_e,n,m,head[N],hp,c[N],mxm,dis[N];

bool vis[N];

bool dij(ll s,ll t,ll w);
inline void addedge(ll from,ll to,ll dis);

void init();
int main()
{   
    ll l,r;
    init();
    if(dij(1,n,1000000001)==0)

    {
        cout<<"AFK";
        return 0;
    }
    l=0; r=mxm;
    while(l<=r)
    {
        int mid=l+r>>1;
        if(dij(1,n,mid))

            r=mid-1;
        else
            l=mid+1;
    }
    cout<<l;
    return 0;
}
bool dij(ll s,ll t,ll w)
{
    if(c[s]>w||c[t]>w)
        return 0;
    memset(dis,0x7f,sizeof(dis));

    memset(vis,0,sizeof(vis));
    priority_queue<node> q;
    dis[s]=0;

    q.push((node){0,s});
    while(!q.empty())
    {
        node tmp=q.top();
        q.pop();
        ll now=tmp.u;
        if(vis[now])
            continue;
        vis[now]=1;
        for(int i=head[now];i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(dis[v]>dis[now]+edge[i].dis)

            {
                dis[v]=dis[now]+edge[i].dis;

                if(!vis[v]&&c[v]<=w)
                    q.push((node){dis[v],v});

            }
        }
    }
    if(dis[t]<=hp)

        return 1;
    else    
        return 0;
}

inline void addedge(ll from,ll to,ll dis)

{
    edge[++n_e].next=head[from];
    edge[n_e].to=to;
    edge[n_e].dis=dis;

    head[from]=n_e;
}
void init()
{
    cin>>n>>m>>hp;
    mxm=-1; 
    for(int i=1;i<=n;i++)
    {
        ll w;
        cin>>w;
        mxm=max(mxm,w);
        c[i]=w;
    }
    for(int i=1;i<=m;i++)
    {
        ll u,v,w;
        cin>>u>>v>>w;
        if(u==v)
            continue;
        addedge(u,v,w);

        addedge(v,u,w);

    }
}

标签:瑞玛,int,luogu,P1462,vis,edge,long,now,dis
来源: https://www.cnblogs.com/nenT/p/11700352.html