Time Limit: 14000/7000 MS (Java/Others)
Memory Limit: 512000/512000 K (Java/Others)
Problem Description
高玩小Q不僅喜歡玩尋寶遊戲,還喜歡一款升級養成類遊戲。在這個遊戲的世界地圖中一共有n個城鎮,編號依次爲1到n。
這些城鎮之間有m條單向道路,第 條單項道路包含四個參數,表示一條從ui號城鎮出發,在號城鎮結束的單向道路,因爲是單向道路,這不意味着小Q可以從沿着該道路走到。小Q的初始等級level爲1,每當試圖經過一條道路時,需要支付點積分,並且經過該道路後,小Q的等級會提升級,到達級。但是每條道路都會在一定意義上歧視低消費玩家,準確地說,如果該次所需積分,那麼小Q不能經過該次道路,也不能提升相應的等級。
注意:本遊戲中等級爲正整數,但是積分可以是任意實數。
小Q位於1號城鎮,等級爲1,現在爲了做任務要到n號城鎮去。這將會是一次奢侈的旅行,請寫一個程序幫助小Q找到需要支付的總積分最少的一條路線,或判斷這是不可能的。
Input
第一行包含一個正整數T(1≤T≤30),表示測試數據的組數。
每組數據第一行包含兩個整數,表示城鎮數和道路數。
接下來m行,每行四個整數,分別表示每條單向道路。
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
一條路徑的
那麼我們只要讓到達n的等級儘量低就行。
然後在此之下走的每一條邊滿足,表示到達的最低等級。
#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;
}