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

题意简述

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

思路

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

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#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;
}
w