列表

详情


NC207440. 芜湖起飞

描述

安徽芜湖有n个机场,一共有m条线路在空管部门报备。
每条线路单向连接两个机场,并且需要的通行时间每天都可能不一样。
具体来说,设目前是第x天,那么第i条线路所需要的通行时间为
一年一共有H天,也就是说,x取[0,H]中的整数。
现在大司马想从1号机场在一天内换乘任意多次航班前往n号机场,他总是选择用时最短的方式,现在他想知道哪一天需要花最长的时间。

输入描述

每个测试点仅包含一组输入数据。
第一行三个整数,表示机场的数量,线路的数量和x的取值范围。
接下来m行,每行四个整数,表示一条线路从u_i机场单向前往v_i机场,并且第x天需要的时间来通行。
同一对机场之间可能有多条航线,一条航线的起点和终点可能相同。
保证在[0,H]中的任意一天,每条航线的长度非负且不超过,且从1号机场可以到达n号机场。

输出描述

输出一行一个整数,表示最长的用时。

示例1

输入:

4 6 2
1 2 -2 6
1 3 3 3
1 4 -1 4
3 2 1 5
3 4 -3 7
2 4 0 5

输出:

4

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 717ms, 内存消耗: 8048K, 提交时间: 2020-05-30 19:38:01

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int n,m,l,r,d[N],vis[N];
int head[N],nex[N],to[N],K[N],B[N],tot;
inline void add(int a,int b,int c,int d){
	to[++tot]=b; nex[tot]=head[a]; K[tot]=c; B[tot]=d; head[a]=tot;
}
priority_queue<pair<int,int> > q;
inline int check(int mid){
	q.push({0,1}); memset(d,0x3f,sizeof d); d[1]=0; memset(vis,0,sizeof vis);
	while(q.size()){
		int u=q.top().second; q.pop();
		if(vis[u]) continue; vis[u]=1;
		for(int i=head[u];i;i=nex[i]) if(d[to[i]]>d[u]+K[i]*mid+B[i]){
			d[to[i]]=d[u]+K[i]*mid+B[i];	q.push({-d[to[i]],to[i]});
		}
	}
	return d[n];
}
signed main(){
	cin>>n>>m>>r;
	for(int i=1,a,b,c,d;i<=m;i++)	scanf("%lld %lld %lld %lld",&a,&b,&c,&d),add(a,b,c,d);
	while(l+10<r){
		int midr=r-(r-l)/3,midl=l+(r-l)/3;
		if(check(midl)>check(midr))	r=midr;
		else	l=midl;
	}
	int res=0; 
	for(int i=l;i<=r;i++)	res=max(res,check(i));
	cout<<res;
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 443ms, 内存消耗: 10600K, 提交时间: 2020-06-26 13:45:41

#include<bits/stdc++.h>
using namespace std;

struct node
{
	long long x,h;
	bool operator<(const node &a)const
	{
		return a.h<h;
	}
}r,f;
priority_queue<node>Q;
vector<int>R[120005],ID[120005];
long long ans=0,D[120005];
int n,m,H,k[120005],b[120005];
long long dij(long long x)
{
	long long i,j,id;
	for(i=1;i<=n;i++)D[i]=2e18;
	r.x=1,D[1]=r.h=0,Q.push(r);
	while(!Q.empty())
	{
		f=Q.top(),Q.pop();
		if(D[f.x]<f.h)continue;
		for(i=0;i<R[f.x].size();i++)
		{
			j=R[f.x][i],id=ID[f.x][i];
			if(f.h+k[id]*x+b[id]<D[j])r.h=D[j]=f.h+k[id]*x+b[id],r.x=j,Q.push(r);
		}
	}
	return D[n];
}
int main()
{
    int i,u,v,l,r,m1,m2;
    scanf("%d%d%d",&n,&m,&H);
    for(i=1;i<=m;i++)
    {
    	scanf("%d%d%d%d",&u,&v,&k[i],&b[i]);
    	R[u].push_back(v),ID[u].push_back(i);
	}
	for(l=0,r=H;r-l>2;)
	{
		m1=l+(r-l)/3,m2=r-(r-l)/3;
		if(dij(m1)<dij(m2))l=m1;
		else r=m2;
	}
	while(l<=r)ans=max(ans,dij(l++));
	printf("%lld\n",ans);
}

上一题