洛谷——P1951 收费站_NOI导刊2009提高(2)
https://www.luogu.org/problem/show?pid=1951
题目描述
在某个遥远的国家里,有n个城市。编号为1,2,3,…,n。
这个国家的政府修建了m条双向的公路。每条公路连接着两个城市。沿着某条公路,开车从一个城市到另一个城市,需要花费一定的汽油。
开车每经过一个城市,都会被收取一定的费用(包括起点和终点城市)。所有的收费站都在城市中,在城市间的公路上没有任何的收费站。
小红现在要开车从城市u到城市v(1<=u,v<=n)。她的车最多可以装下s升的汽油。在出发的时候,车的油箱是满的,并且她在路上不想加油。
在路上,每经过一个城市,她都要交一定的费用。如果某次交的费用比较多,她的心情就会变得很糟。所以她想知道,在她能到达目的地的前提下,她交的费用中最多的一次最少是多少。这个问题对于她来说太难了,于是她找到了聪明的你,你能帮帮她吗?
输入输出格式
输入格式:
第一行5个正整数,n,m,u,v,s,分别表示有n个城市,m条公路,从城市u到城市v,车的油箱的容量为s升。
接下来的有n行,每行1个整数,fi表示经过城市i,需要交费fi元。
再接下来有m行,每行3个正整数,ai,bi,ci(1<=ai,bi<=n),表示城市ai和城市bi之间有一条公路,如果从城市ai到城市bi,或者从城市bi到城市ai,需要ci升的汽油。
输出格式:
仅一个整数,表示小红交费最多的一次的最小值。
如果她无法到达城市v,输出-1.
输入输出样例
4 4 2 3 8 8 5 6 10 2 1 2 2 4 1 1 3 4 3 4 3
8
说明
【数据规模】
对于60%的数据,满足n<=200,m<=10000,s<=200
对于100%的数据,满足n<=10000,m<=50000,s<=1000000000
对于100%的数据,满足ci<=1000000000,fi<=1000000000,可能有两条边连接着相同的城市。
做法同http://www.cnblogs.com/Shy-key/p/7684142.html, 数据更强,换了堆优化的Dijkstra
1 #include <algorithm> 2 #include <cstdio> 3 #include <queue> 4 5 #define max(a,b) (a>b?a:b) 6 7 inline void read(int &x) 8 { 9 x=0; register char ch=getchar(); 10 for(; ch>'9'||ch<'0'; ) ch=getchar(); 11 for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0'; 12 } 13 14 const int INF(0x3f3f3f3f); 15 const int N(10626); 16 const int M(50626); 17 int n,m,s,t,b,f[N],a[N]; 18 int head[N],sumedge; 19 struct Edge { 20 int v,next,w; 21 Edge(int v=0,int next=0,int w=0):v(v),next(next),w(w){} 22 }edge[M<<1]; 23 inline void ins(int u,int v,int w) 24 { 25 edge[++sumedge]=Edge(v,head[u],w),head[u]=sumedge; 26 edge[++sumedge]=Edge(u,head[v],w),head[v]=sumedge; 27 } 28 29 struct Node { 30 int pos;long long dis; 31 Node() {pos=0,dis=0;} 32 bool operator < (const Node&x)const 33 { 34 return dis>x.dis; 35 } 36 }u,v; 37 38 bool vis[N]; 39 long long dis[N]; 40 std::priority_queue<Node>que; 41 42 int L,R,Mid,ans; 43 inline bool check(int s,int x) 44 { 45 if(f[s]>x) return 0; 46 for(int i=1; i<=n; ++i) dis[i]=1ll*INF,vis[i]=0; 47 for(; !que.empty(); ) que.pop(); 48 u.dis=dis[s]=0; u.pos=s; que.push(u); 49 for(; !que.empty(); ) 50 { 51 u=que.top(); que.pop(); 52 if(vis[u.pos]) continue; vis[u.pos]=1; 53 for(int i=head[u.pos]; i; i=edge[i].next) 54 { 55 v.pos=edge[i].v; 56 if(f[v.pos]>x) continue; 57 if(dis[v.pos]<=dis[u.pos]+1ll*edge[i].w) continue; 58 v.dis=dis[v.pos]=dis[u.pos]+1ll*edge[i].w; que.push(v); 59 } 60 } 61 return dis[t]<b; 62 } 63 64 int Presist() 65 { 66 read(n),read(m),read(s),read(t),read(b); 67 for(int i=1; i<=n; ++i) read(f[i]),a[i]=f[i]; 68 for(int u,v,w,i=1; i<=m; ++i) 69 read(u),read(v),read(w),ins(u,v,w); 70 std::sort(a+1,a+n+1); 71 for(L=0,R=n; L<=R; ) 72 { 73 Mid=L+R>>1; 74 if(check(s,a[Mid])) 75 { 76 ans=a[Mid]; 77 R=Mid-1; 78 } 79 else L=Mid+1; 80 } 81 if(!ans) puts("-1"); 82 else printf("%d\n",ans); 83 return 0; 84 } 85 86 int Aptal=Presist(); 87 int main(int argc,char**argv){;}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步