[hdu6290]奢侈的旅行

Time Limit: 14000/7000 MS (Java/Others)
Memory Limit: 512000/512000 K (Java/Others)

Problem Description
高玩小Q不僅喜歡玩尋寶遊戲,還喜歡一款升級養成類遊戲。在這個遊戲的世界地圖中一共有n個城鎮,編號依次爲1到n。
這些城鎮之間有m條單向道路,第ii 條單項道路包含四個參數ui,vi,ai,biu_i,v_i,a_i,b_i,表示一條從ui號城鎮出發,在viv_i號城鎮結束的單向道路,因爲是單向道路,這不意味着小Q可以從viv_i沿着該道路走到uiu_i。小Q的初始等級level爲1,每當試圖經過一條道路時,需要支付cost=log2(level+ailevel)cost=log_2(\frac {level+a_i}{level})點積分,並且經過該道路後,小Q的等級會提升aia_i級,到達level+ailevel+a_i級。但是每條道路都會在一定意義上歧視低消費玩家,準確地說,如果該次所需積分cost<bicost<b_i,那麼小Q不能經過該次道路,也不能提升相應的等級。

注意:本遊戲中等級爲正整數,但是積分可以是任意實數。

小Q位於1號城鎮,等級爲1,現在爲了做任務要到n號城鎮去。這將會是一次奢侈的旅行,請寫一個程序幫助小Q找到需要支付的總積分最少的一條路線,或判斷這是不可能的。

Input
第一行包含一個正整數T(1≤T≤30),表示測試數據的組數。
每組數據第一行包含兩個整數n,m(2n100000,1m200000)n,m(2≤n≤100000,1≤m≤200000),表示城鎮數和道路數。
接下來m行,每行四個整數ui,vi,ai,bi(1ui,vin,uivi,0ai109,0bi60)u_i,v_i,a_i,b_i(1≤u_i,v_i≤n,u_i≠v_i,0≤a_i≤10^9,0≤b_i≤60),分別表示每條單向道路。

Output
對於每組數據,輸出一行一個整數,即最少所需的總積分的整數部分,如:4.9999輸出4,1.0輸出1。若不存在合法路線請輸出−1。

Sample Input

1
3 3
1 2 3 2
2 3 1 6
1 3 5 0

Sample Output

2

題解:
考慮log2
一條路徑的cost=log2((1+a1)/(1))+log2((1+a1+a2)/(1+a1))+log2((1+a1+a2+a3)/(1+a1+a2))+...+log2((1+a1+a2+...+ax)/(1+a1+a2+...+ax1))=log2(1+a1+a2+...+ax)cost=log_2((1+a_1)/(1))+log_2((1+a_1+a_2)/(1+a_1))+log_2((1+a_1+a_2+a_3)/(1+a_1+a_2))+...+log_2((1+a_1+a_2+...+a_x)/(1+a_1+a_2+...+a_{x-1})) =log_2(1+a_1+a_2+...+a_x)
那麼我們只要讓到達n的等級儘量低就行。
然後在此之下走的每一條邊滿足(levelui+w)/levelui<2bi(level_{u_i} + w) / level_{u_i} < 2^{b_i}levelilevel_{i}表示到達ii的最低等級。

#include<bits/stdc++.h>
#define ll long long 
#define pa pair<ll,int>
using namespace std;
const ll INF=1e18;
struct edge{
	int to;
	ll a,b;
};
int n,m;
vector<edge>G[100004];
ll dis[100004];
bool vis[100004];
priority_queue<pa,vector<pa>,greater<pa> >q;

void dijkstra(int st){
	for(int i=1;i<=n;i++){
		dis[i]=INF;
		vis[i]=0;
	}
	dis[st]=1;
	q.push({1LL,st});
	while(!q.empty()){
		int x=q.top().second;q.pop();
		if(vis[x])continue;
		vis[x]=1;
		for(int i=0;i<G[x].size();i++){
			int to=G[x][i].to;
			ll w=G[x][i].a,b=G[x][i].b;
			if((w+dis[x])/dis[x]<b)continue;
			if( dis[to]>dis[x]+w){
				dis[to]=dis[x]+w;
				q.push({dis[to],to});
			}
		}
	}
}
int w33ha(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)G[i].clear();
	for(int i=1;i<=m;i++){
		int u,v;ll a,b;
		scanf("%d%d%lld%lld",&u,&v,&a,&b);
		G[u].push_back((edge){v,a,(1LL<<b)});
	}
	dijkstra(1);
	if(dis[n]==INF)puts("-1");
	else printf("%lld\n",(ll)floor(log2(dis[n])));
	return 0;
}
int main(){
	int T;scanf("%d",&T);
	while(T--)w33ha();
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章