Hdu 6290 奢侈的旅行

Hdu 6290 奢侈的旅行(最短路:dijkstra算法(邻近表优先队列解法))

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6290
在这里插入图片描述
在这里插入图片描述
这道题目限制点非常多,首先是在t极限为30的情况下,n最大为1e5,明显裸的迪杰斯特拉(3e11的时间复杂度,就算给了7秒也是一定会超时)是过不去的,但是因为道路数量限制在了2e5,那就可以用优先队列优化,极限复杂度也就是跑完所有道路
6e6的复杂度完全够了。
解题思路:dist数组用来保存到点的最低等级,初始化dist数组要注意,因为a<=1e9,那极限等级应该是99,999,000,000,000,初始化数据一定要比这个数大,这个坑点太深了,错了好久就是不知道哪错了,都怀疑精度丢失了,没想到题目给了这种坑点。然后因为城市数量太多,邻近矩阵空间复杂度太高,所以用邻近表写(空间复杂度就是城市数量),然后就是正常的迪杰斯特拉操作了,注意和搜索的区别就是vis标记数组在该点从队列弹出后在进行标记,保证这个点能走的所有路都会被遍历

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Edge{
    int from,to,nex,a,b;
}edge[200005];
#define inf 0x3f3f3f3f3f3f3f  //注意,inf的值一定要特别大 a的最大值是1e9,题目极限等级就是1e14,不能比1e14小
int head[100005],cnt=1,vis[100005];
ll dist[100005];
inline void add(int from,int to,int a,int b){
    edge[cnt].from=from;
    edge[cnt].to=to;
    edge[cnt].a=a;
    edge[cnt].b=b;
    edge[cnt].nex=head[from];
    head[from]=cnt;
    cnt++;
}
inline ll read(){
    ll res=0;
    bool flag=true;
    char c;
    if((c=getchar())&&c=='-'){
        flag=false;
    }else if(c>='0'&&c<='9'){
        res=c-'0';
    }
    while((c=getchar())&&c>='0'&&c<='9'){
        res=(res<<3)+(res<<1)+c-'0';
    }
    return flag?res:-res;
}
inline void out(ll res){
    if(res<0){
        putchar('-');
        res*=-1;
    }
    if(res>9)out(res/10);
    putchar(res%10+'0');
}
int n,m;
struct node{
    ll a,l;//当前位置,当前等级
    friend bool operator < (const node &a,const node &b){
        return a.l>b.l;
    }
}now;
inline bool check(ll level,ll aa,ll bb){//判断满不满足题意
    double l=level,a=aa,b=bb;
    if(log2((1.0*l+a)/l)<1.0*b)return false;
    return true;
}
inline void Dijkstra(){
    for(int i=1;i<=n;i++){
        dist[i]=inf;
    }
    dist[1]=1;//dist保存到i点的最低等级,相当于记忆化操作
    priority_queue<node>q;
    q.push(node{1,1});
    while(!q.empty()){
        now=q.top();
        q.pop();
        if(vis[now.a]==1)continue;//如果这个点已经标记过了,说明所有这个点的路都走过了,就没必要再来一次
        vis[now.a]=1;
        for(int i=head[now.a];i!=-1;i=edge[i].nex){
            if(check(now.l,edge[i].a,edge[i].b)){//满足题意cast>=b
                if(dist[edge[i].to]>dist[now.a]+edge[i].a){//通过当前点到下一个点是否等级会更低
                    dist[edge[i].to]=dist[now.a]+edge[i].a;//更新到这个点的最小等级
                    q.push(node{edge[i].to,dist[edge[i].to]});
                }
            }
        }
    }
    if(dist[n]==inf){
        out(-1);
    }else{
        out((ll)log2(dist[n]));
    }
    putchar('\n');
}
int main() {
    int t=read();
    while(t--){
        n=read(),m=read();
        for(int i=1;i<=n;i++){
            head[i]=-1;
            vis[i]=0;
        }
        cnt=1;
        for(int i=0;i<m;i++){
            int from=read(),to=read(),a=read(),b=read();
            add(from,to,a,b);
        }
        Dijkstra();
    }
    return 0;
}
发布了35 篇原创文章 · 获赞 3 · 访问量 890

猜你喜欢

转载自blog.csdn.net/weixin_43823753/article/details/104580201