洛谷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 namespace std ;
 5
 6 const int N = 10011 , M = 50011 ;
 7 struct node{
 8     LL to,pre,val ;
 9 }e[M*2];
10 struct edge{
11     LL x,y,val ;
12 }beg[M];
13 LL n,m,b,cnt,point[N],head[N],mx,blood,dist[N] ;
14 bool visit[N] ;
15 queue<LL> Q ;
16
17 inline LL read()
18 {
19     LL x = 0 , f = 1 ;
20     char ch = getchar() ;
21     while(ch<‘0‘||ch>‘9‘) { if(ch==‘-‘) f = -1 ; ch = getchar() ; }
22     while(ch>=‘0‘&&ch<=‘9‘) { x = x * 10+ch-48 ; ch = getchar() ; }
23     return x * f ;
24 }
25
26 inline void add(int x,int y,int val)
27 {
28     e[cnt].to = y ;
29     e[cnt].pre = head[x] ;
30     e[cnt].val = val ;
31     head[x] = cnt++ ;
32 }
33
34 inline bool check( int mid )
35 {
36     LL u,v ;
37     For(i,0,n) head[i] = -1,dist[i] = (1LL<<62) ;
38     cnt = 0 ;
39     For(i,1,m) {
40         if( point[beg[ i ].x] > mid ) continue ;
41         if( point[beg[ i ].y] > mid ) continue ;
42         add( beg[ i ].x,beg[ i ].y,beg[ i ].val ) ;
43         add( beg[ i ].y,beg[ i ].x,beg[ i ].val ) ;
44     }
45     while(!Q.empty()) Q.pop() ;
46     Q.push(1) ; dist[ 1 ] = 0 ; visit[ 1 ] = 1 ;
47     while(!Q.empty()) {
48         u = Q.front() ;
49         Q.pop() ;
50         visit[u] = 0 ;
51         for(int i=head[u];~i;i=e[i].pre) {
52             v = e[ i ].to ;
53             if( dist[ u ] +  e[ i ].val < dist[ v ] ) {
54                 dist[ v ] = dist[ u ] + e[ i ].val ;
55                 if( !visit[ v ] ) {
56                     visit[ v ] = 1 ;
57                     Q.push(v) ;
58                 }
59             }
60         }
61     }
62     if( dist[n]>=blood || dist[n]==dist[0] ) return 0 ;   // 血量不够 或者 不能到达
63     return 1 ;
64 }
65
66 inline void erfen()
67 {
68     LL l = 0 , r = mx+1,mid ;
69     while( l < r ) {
70         mid = ( l+r )/2 ;
71         if( check( mid ) )
72             r = mid ;
73         else
74             l = mid+1 ;
75     }
76     if(r==mx+1) {
77         printf("AFK\n") ;
78         exit(0) ;
79     }
80     printf("%d\n",r) ;
81 }
82
83 int main()
84 {
85     n = read() ; m = read() ; blood = read() ;
86     For(i,1,n) point[ i ] = read(),mx = max(mx,point[ i ]) ;
87     For(i,1,m) {
88         beg[ i ].x = read() ; beg[ i ].y = read() ; beg[ i ].val = read() ;
89     }
90     erfen() ;
91     return 0 ;
92 }
时间: 2024-10-01 16:08:25

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

洛谷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],

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

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

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

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

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

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

[Luogu P1462] 通往奥格瑞玛的道路 (二分答案+最短路径)

题面 传送门:https://www.luogu.org/problemnew/show/P1462 Solution 这道题如果去除掉经过城市的收费.那么就是裸的最短路 但是题目要求经过城市中最多的一次性收费的最小值,也就是说让经过的最大值尽可能小 那我们可以考虑二分这个最大值 一切收费大于我们二分的值的城市统统不走 在最短路那里改一下就好了 然后就OjbK了 时间复杂度 O(n*logn*log b) Code //Luogu P1462 通往奥格瑞玛的道路 //May,27th,2018

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

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

洛谷 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 通往奥格瑞玛的道路 (二分+最短路)

题目 P1462 通往奥格瑞玛的道路 给定\(n\)个点\(m\)条边,每个点上都有点权\(f[i]\),每条边上有边权,找一条道路,使边权和小于给定的数\(b\),并使最大点权最小. 解析 二分一下钱,然后跑最短路,判断一下如果只有这么多钱的话能不能到终点(最短路边权和是不是不超过\(b\)),套个最短路板子,套个二分板子,没了. 代码 //二分+最短路 #include <bits/stdc++.h> using namespace std; const int N = 1e5 + 10;

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

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