NC221309. 小明运货
描述
输入描述
第一行 6 个正整数,,,,,,分别代表城市里的地点数量、公路条数、小明的起点、小明的终点、货车的重量、以及小明最大行驶的路程。
接下来的行,每行有四个正整数、、、,分别描述每条公路的起始地点、终止地点、限重以及这条公路的路程。
请注意,每条公路是双向的,两个地点之间也有可能不止一条公路。不保证和是连通的。
输出描述
如果小明无论如何也无法完成运输,请输出 -1。如果小明能运的重量是0(即只能空车往返),也请输出-1。
否则输出一个正整数,代表能拉的货物重量的最大值。
示例1
输入:
3 3 1 3 10 11 1 2 14 3 3 2 12 3 1 3 11 4
输出:
2
说明:
最大能运输的重量为2:示例2
输入:
3 3 1 3 10 9 1 2 14 3 3 2 12 3 1 3 11 4
输出:
1
C++(clang++11) 解法, 执行用时: 30ms, 内存消耗: 892K, 提交时间: 2021-05-08 15:46:26
#include<bits/stdc++.h> using namespace std; struct edge { int to,p,d,next; edge(){} edge(int a,int b,int c,int d):to(a),p(b),d(c),next(d){} }E[20005]; struct node { long long x,h; bool operator<(const node &a)const { return a.h<h; } }f; priority_queue<node>Q; int n,m,tot=0,head[10005]; long long dis[2][10005]; void add(int x,int y,int p,int d) { E[++tot]=edge(y,p,d,head[x]); head[x]=tot; } void dij(int sx,int w,bool id) { int i,j,p; long long d; for(i=1;i<=n;i++)dis[id][i]=1e18; dis[id][sx]=0,Q.push({sx,0}); while(!Q.empty()) { f=Q.top(),Q.pop(); if(dis[id][f.x]<f.h)continue; for(i=head[f.x];i;i=E[i].next) { j=E[i].to,p=E[i].p,d=E[i].d; if(p<w)continue; if(dis[id][j]>f.h+d)dis[id][j]=f.h+d,Q.push({j,dis[id][j]}); } } } int main() { int i,j,sx,ex,w,d,u,v,p,dd,l,r,mid,ans=-1; scanf("%d%d%d%d%d%d",&n,&m,&sx,&ex,&w,&d); while(m--)scanf("%d%d%d%d",&u,&v,&p,&dd),add(u,v,p,dd),add(v,u,p,dd); dij(ex,w,1); for(l=1,r=1e9;l<=r;) { mid=(l+r)>>1; dij(sx,mid+w,0); if(dis[0][ex]+dis[1][sx]>d)r=mid-1; else ans=mid,l=mid+1; } printf("%d\n",ans); return 0; }
Python3(3.9) 解法, 执行用时: 1817ms, 内存消耗: 8664K, 提交时间: 2021-05-11 12:28:46
n, m, x, y, w, d = map(int, input().strip().split()) graph = [list() for _ in range(n + 1)] for i in range(m): u, v, p, dis = map(int, input().strip().split()) graph[u].append([v, p, dis]) graph[v].append([u, p, dis]) from queue import PriorityQueue def check(line): global n, m, x, y dis = [10000000000] * (n + 1) flag = [0] * (n + 1) dis[x] = 0 q = PriorityQueue() q.put((0, x)) while not q.empty(): tmp, node = q.get() if flag[node] == 1: continue flag[node] = 1 for a, b, c in graph[node]: if dis[a] > dis[node] + c and b >= line: dis[a] = dis[node] + c q.put((dis[a], a)) return dis[y] lx = check(w) left = w right = 1000000000 ans = -1 while left <= right: mid = (left + right) // 2 if check(mid) + lx <= d: ans = mid left = mid + 1 else: right = mid - 1 if ans == w or ans == -1: print(-1) else: print(ans - w)