洛谷 1462 通往奥格瑞玛的道路 题解 发表于 2020-02-10 | 更新于 2019-12-01 | 阅读次数: 20 本文字数: 664 字 | 阅读时长 ≈ 3 分钟 题意简述nn个点mm条边的无向图,点边均有权。给定bb。请你找到一个从1到n的路使得边权和<=b且点权的最大值最小。 思路二分+最短路。对于一个mid,把所有点权<=mid的点之间连边,跑最短路,看是否<=b即珂。 代码复制123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128#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;}