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

题目:https://www.luogu.org/problemnew/show/P1462

二分答案。

为什么djkstra不行,spfa可以?

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
const int N=1e5+5,M=5e5+5;
int n,m,head[N],xnt;
ll b,v[N],l,r,ans=-1,dis[N];
bool vis[N];
struct Edge{
    int next,to;ll w,c;
    Edge(int n=0,int t=0,ll w=0,ll c=0):next(n),to(t),w(w),c(c) {}
}edge[M<<1];
struct Node{
    int bh;ll c;
    Node(int b=0,ll c=0):bh(b),c(c) {}
    bool operator <(const Node &a)const
    {return c<a.c;}
};
void add(int x,int y,ll z)
{
    edge[++xnt]=Edge(head[x],y,z,v[y]);head[x]=xnt;
    edge[++xnt]=Edge(head[y],x,z,v[x]);head[y]=xnt;
}
bool dj(ll mid)
{
    printf("mid=%lld\n",mid);
    memset(dis,11,sizeof dis);
    memset(vis,0,sizeof vis);
    queue<Node> q;
    dis[1]=0;q.push(Node(1,0));
    while(q.size())
    {
        int k=q.front().bh;q.pop();
        while(q.size()&&vis[k])k=q.front().bh,q.pop();
        if(vis[k])break;vis[k]=1;
        for(int i=head[k],v;i;i=edge[i].next)
        {
//            if(edge[i].c<=mid)printf("1");
//            if(dis[v=edge[i].to]>dis[k]+edge[i].w)printf("2");
//            if(dis[k]+edge[i].w<=b)printf("3");printf("v=%d\n",v);
            if(edge[i].c<=mid&&dis[v=edge[i].to]>dis[k]+edge[i].w&&dis[k]+edge[i].w<=b)
            {dis[v]=dis[k]+edge[i].w;q.push(Node(v,dis[v]));if(v==n)return true;}
        }
    }
    return false;
}
bool spfa(ll mid)
{
    memset(dis,11,sizeof dis);
    memset(vis,0,sizeof vis);
    queue<int> q;
    q.push(1);dis[1]=0;vis[1]=1;
    while(q.size())
    {
        int k=q.front();q.pop();vis[k]=0;
        for(int i=head[k],v;i;i=edge[i].next)
        if(edge[i].c<=mid&&dis[v=edge[i].to]>dis[k]+edge[i].w&&dis[k]+edge[i].w<=b)
            {
                dis[v]=dis[k]+edge[i].w;
                if(!vis[v])vis[v]=1,q.push(v);
                if(v==n)return true;
            }
    }
    return false;
}
int main()
{
//    freopen("洛谷1462#8.in","r",stdin);
    scanf("%d%d%lld",&n,&m,&b);int x,y;ll z;
    for(int i=1;i<=n;i++)scanf("%lld",&v[i]),r=max(r,v[i]);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%lld",&x,&y,&z);
        add(x,y,z);
    }
//    printf("l=%lld r=%lld\n",l,r);
    while(l<=r)
    {
        ll mid=((l+r)>>1);
        if(spfa(mid))ans=mid,r=mid-1;
        else l=mid+1;
    }
    if(ans==-1)printf("AFK");
    else printf("%lld",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/Narh/p/8922673.html

时间: 2024-08-03 06:31:44

洛谷1462通往奥格瑞玛的道路的相关文章

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

本题地址:http://www.luogu.org/problem/show?pid=1462 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯,有n个城市.编号为1,2,3,...,n. 城市之间有m条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联盟的攻击,进而损失一定的血量. 没经过一个城市,都会被收取一定的过路费(包括起点和终点

洛谷P1462 通往奥格瑞玛的道路 二分答案+最短路SPFA

洛谷P1462 通往奥格瑞玛的道路二分答案+最短路SPFA 二分交费最多的一次的钱数 然后只将符合要求的边加入图中 如果到终点的最短路大于等于血量 或者直接起点不能到达终点那么说明不符合要求 需要加大答案 时间复杂度 (log答案)* Ek 需要注意如果本来就不能到达 那么直接输出AFK 1 #include <bits/stdc++.h> 2 #define LL long long 3 #define For(i,j,k) for(int i=j;i<=k;i++) 4 using

洛谷P1462 通往奥格瑞玛的道路

P1462 通往奥格瑞玛的道路 219通过 1.2K提交 题目提供者gconeice 标签二分图论洛谷原创 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 RE好多.. 到底怎么判断AFK啊 看不懂题目.. 建议修改题目 究竟是血量为负算挂还是生命… 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯,有n个城市.编号为1,2,3,...,

洛谷 P1462 通往奥格瑞玛的道路(spfa+二分搜索)(4boy)

原题:http://www.luogu.org/problem/show?pid=1462#sub 4boy: 大意:给出n个城市,有m条路,每经过一个城市都要交钱,每经过一条道路都要扣HP,有HP上限:要从1走到n, 求在HP没扣完的情况下,从1到n经过城市的最大花费的最小值. 思路:用二分搜索cost的值的最小值,用spfa搜索从1到n所需的最少HP,在spfa中判断cost[i]与x详见代码注释: 1 #include<iostream> 2 #include<cstring>

洛谷P1462 通往奥格瑞玛的道路[二分答案 spfa 离散化]

题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯,有n个城市.编号为1,2,3,...,n. 城市之间有m条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联盟的攻击,进而损失一定的血量. 没经过一个城市,都会被收取一定的过路费(包括起点和终点).路上并没有收费站. 假设1为暴风城,n为奥格瑞玛,而他的血量最多为b,出发时他的血量是满的.

洛谷 P1462 通往奥格瑞玛的道路

题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯,有n个城市.编号为1,2,3,...,n. 城市之间有m条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联盟的攻击,进而损失一定的血量. 每次经过一个城市,都会被收取一定的过路费(包括起点和终点).路上并没有收费站. 假设1为暴风城,n为奥格瑞玛,而他的血量最多为b,出发时他的血量是满的

洛谷 P1462 通往奥格瑞玛的道路 Label: 最小化最大值 &amp;&amp; spfa (存多条边示例)

题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯,有n个城市.编号为1,2,3,...,n. 城市之间有m条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联盟的攻击,进而损失一定的血量. 没经过一个城市,都会被收取一定的过路费(包括起点和终点).路上并没有收费站. 假设1为暴风城,n为奥格瑞玛,而他的血量最多为b,出发时他的血量是满的.

洛谷 [P1426] 通往奥格瑞玛的道路

题目中的表述很明显是一道二分答案+最短路的题目,二分收取的费用x判断能否到达奥格瑞玛.检验函数用SPFA跑最短路,注意,费用高于x的点不能使用. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> using namespace std; const int MAX

洛谷P1462通往奥格瑞玛的道路——二分答案最短路

题目:https://www.luogu.org/problemnew/show/P1462 最大值最小问题,二分答案. 代码如下: #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int const MAXN=1e5+5; queue<int>q; int n,m,b,cost[MAXN],head[MAXN],