HDU - 6290

题目链接:HDU - 6290


对判断是否能走,我们可以发现等级越低,越能过去。

然后判断消费:假设每次经过的边的等级提升值分别为:a1,a2,a3…ak

我们可以发现代价为:log2(1+a1+a2+a3+…+ak),也是等级越低越优,所以我们对等级跑最短路即可。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10,M=N<<1;
int n,m,vis[N],d[N];
int head[N],nex[M],to[M],wa[M],wb[M],tot;
inline void add(int a,int b,int c,int d){
	to[++tot]=b; nex[tot]=head[a]; wa[tot]=c; wb[tot]=d; head[a]=tot;
}
void Dijkstra(){
	priority_queue<pair<int,int> > q; q.push({-1.0,1}); d[1]=1;
	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(log2(1.0+(1.0*wa[i])/d[u])>=1.0*wb[i]){
			if(d[to[i]]>d[u]+wa[i]){
				d[to[i]]=d[u]+wa[i];	q.push({-d[to[i]],to[i]});
			}
		}
	}
}
void solve(){
	cin>>n>>m; tot=0;
	for(int i=1;i<=n;i++)	head[i]=vis[i]=0,d[i]=1e16;
	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);
	Dijkstra(); 
	if(d[n]>1e15)	puts("-1");
	else	printf("%lld\n",(int)log2(1.0*d[n]));
}
signed main(){
	int T; cin>>T; while(T--) solve();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/107783377
hdu