Two Paths HDU - 6181 -次短路-A*

本文探讨了A*算法在求解次短路径问题中的应用,通过估价函数f=g+h,其中g是从起点到当前节点的实际代价,h是预估从当前节点到目标节点的代价,利用堆优化的Dijkstra算法预处理出每个点到终点的距离,从而解决了第K短路径的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • Two Paths

  •  HDU - 6181 
  • 题意:很直接就是求次短路。
  • 思路:简单谈一谈我所了解的A*,核心为估价函数 f=g+h,f为所求距离,g为从起点bfs到次的距离。
  • h为估计的从此处到终点的距离,说是估计不过是预处理而已,堆优化dijkstra,预处理出dis[]数组
  • 里面存储的是每个点到终点n的距离。然后就是A*算法了,打一个变量记录第几次访问到终点
  • 当访问终点次数达到K时输出f即可。g就根据bfs顺序不断更新,h就是预处理出来的dis这样A*算法就可以解决第K短路问题了。
  • #include <bits/stdc++.h>
    using namespace std;
    const long long inf=1e15;
    struct node
    {
        long long to,w,next;
    } e[200005];
    struct nodee
    {
        long long u,w;
        bool operator < (const nodee &b)const
        {
            return b.w<w;
        }
    };
    struct nodeee
    {
        long long u,f,h;
        bool operator < (const nodeee &b)const
        {
            if(b.h==h)return f>b.f;
            return h>b.h;
        }
    };
    long long n,m;
    long long  head[100005],cnt=1,vis[100005];
    long long dis[100005];
    void add(long long  u,long long v,long long  w)
    {
        e[cnt].to=v;
        e[cnt].w=w;
        e[cnt].next=head[u];
        head[u]=cnt++;
    }
    void d()
    {
        for(long long  i=1; i<=n; i++)
        {
            dis[i]=inf;
            vis[i]=0;
        }
        priority_queue<nodee>q;
        q.push(nodee{n,0});
        dis[n]=0;
        while(!q.empty())
        {
            long long  x=(q.top()).u;
            q.pop();
            if(vis[x])continue;
            vis[x]=1;
            for(long long i=head[x]; i!=-1; i=e[i].next)
            {
                long long to=e[i].to;
                long long w=e[i].w;
                if(!vis[to]&&dis[to]>dis[x]+w)
                {
                    dis[to]=dis[x]+w;
                    q.push(nodee{to,dis[to]});
                }
            }
        }
    }
    
    long long bfs()
    {
        priority_queue<nodeee>q;
        q.push(nodeee{1,0,0});
        long long int cnt=0;
        while(!q.empty())
        {
            nodeee x=q.top();
            q.pop();
            if(x.u==n)cnt++;
            if(cnt==2)return x.f;
            for(int i=head[x.u]; i!=-1; i=e[i].next)
            {
                long long to=e[i].to;
                long long w=e[i].w;
                long long f=w+x.f;
                long long h=f+dis[to];
                q.push(nodeee{to,f,h});
            }
        }
    
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            memset(head,-1,sizeof(head));
            cnt=1;
            scanf("%lld %lld",&n,&m);
            long long u,v,w;
            for(long long  i=1; i<=m; i++)
            {
                scanf("%lld %lld %lld",&u,&v,&w);
                add(u,v,w);
                add(v,u,w);
            }
            d();
            long long ans=bfs();
            printf("%lld\n",ans);
        }
        return 0;
    }
    

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值