奢侈的旅行Time Limit: 14000/7000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others)Total Submission(s): 2005 Accepted Submission(s): 417 Problem Description 高玩小Q不仅喜欢玩寻宝游戏,还喜欢一款升级养成类游戏。在这个游戏的世界地图中一共有n 个城镇,编号依次为1 到n 。
Input 第一行包含一个正整数T(1≤T≤30) ,表示测试数据的组数。
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 |
由于今年还有女生赛,然后就去看了看我们去年打的女生赛的题,正好在写最短路,然后想到去年这个时候我们什么算法都不会,只会不用算法的签到题,幸运苟了一个铜末,今年再来看题目觉得自己稍微有一点点长进。这题我也就改了十几遍吧,怎么都找不到bug,然后无奈之下找了别人的代码来对拍,发现我少了个初始化。嗯我是zz。
这题就是一个很简单的dijkstra最短路堆优化,然后利用题目信息将数据进行化简,发现其实就是一道最短路题再把最终结果取个log2就好了。
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
const int MAXN=200005;
const long long INF=1ll << 60;
int n, m;
long long p[61];
struct qnode{
int v;
long long a;
int b;
qnode(int _v=0,long long _a = 0):v(_v),a(_a){}
bool operator <(const qnode &r)const{
return a > r.a;
}
};
struct Edge{
int v;
long long a;
int b;
Edge(int _v=0,long long _a=0, int _b = 0):v(_v),a(_a),b(_b){}
};
vector<Edge>E[MAXN];
bool vis[MAXN];
long long dist[MAXN];
void Dijkstra(int n,int start){
memset(vis,false,sizeof(vis));
for(int i=1;i<=n;i++) dist[i]=INF;
priority_queue<qnode>que;
while(!que.empty()) que.pop();
dist[start]=1;
que.push(qnode(start,1));
qnode tmp;
while(!que.empty()){
tmp=que.top();
que.pop();
int u=tmp.v;
if(vis[u])continue;
vis[u]=true;
for(int i = 0; i < E[u].size(); i++){
int v = E[u][i].v;
if(1 + E[u][i].a / dist[u] < p[E[u][i].b]) continue;
if(dist[v] > dist[u] + E[u][i].a)
{
dist[v] = dist[u] + E[u][i].a;
que.push(qnode(v,dist[v]));
}
}
}
}
void addedge(int u,int v,long long w1, int w2){
E[u].push_back(Edge(v,w1, w2));
}
int main()
{
//freopen("test2.in","w",stdout);
p[0] = 1;
for(int i = 1; i < 61; i++) p[i] = p[i-1] * 2;
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
for(int i = 0; i <= n; i++) E[i].clear();
for(int i = 0; i < m; i++)
{
int u, v;
long long a1;
int b1;
scanf("%d%d%lld%d", &u, &v, &a1, &b1);
addedge(u, v, a1, b1);
}
Dijkstra(n, 1);
if(dist[n] == INF) printf("-1\n");
else printf("%.0f\n", floor(log2(dist[n])));
}
return 0;
}