18362 寻找Megumi 迪杰斯特拉+优先队列优化

该博客介绍了如何使用单源最短路径算法解决在线判题平台OJ新生赛中的路径最短问题。通过邻接表存储结构和优先队列优化,避免了弗洛伊德算法可能导致的时间超限,确保了算法效率。代码示例展示了从点1出发,经过K个点到达点n的最短路径计算过程。
摘要由CSDN通过智能技术生成

传送门: OJ 新生赛 2018华山论剑。

 

题目大意:从点1出发,按次序经过K个点,再走到点n。求最短路径。

解题思路:弗洛伊德算法可能超时,所以用单源最短路径算法,依次求出从1到a1,a1到a2.......ak到n的最短路径长度。为降低复杂度,必须使用邻接表存储结构,同时用优先队列进行优化。

#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
struct node
{
    int id,v;
    bool operator<(const node B)const
    {
        return v>B.v;
    }
};
int t,n,m,a[1005],x,y,z,k,d[1005],v[1005];
vector<pair<int,int> >e[1005];
void dij(int cur)
{ 
    memset(d,127/3,sizeof d);
    memset(v,0,sizeof v);
    priority_queue<node>pq;
    d[cur]=0;
    int i,j;
    for(i=1;i<=n;i++)
    pq.push({i,d[i]});
    for(i=1;i<=n;i++)
    {
        while(v[pq.top().id]) /**< 队列会进入id相同但v不同的重复元素,所以队头可能是之前已经选走的id */
            pq.pop();       /**< 已选过的结点不能再选,删除 */
        int t=pq.top().id;
        pq.pop();
        v[t]=1;
        for(j=0;j<e[t].size();j++)
        {
            int y=e[t][j].first,z=e[t][j].second;
            if(d[y]>d[t]+z)
            {
                d[y]=d[t]+z;
                pq.push({y,d[y]});
            }
        }
    }
}
int main()
{
    int i,j;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        for(i=1;i<=n;i++)
            e[i].clear();
        memset(v,0,sizeof v);
        for(i=1;i<=m;i++)
        {
            cin>>x>>y;/**< 实际上本题目实际无需存储边长,边长均为1,为方便读者,此代码采用标准写法存边 */
            e[x].push_back({y,1});
            e[y].push_back({x,1});
        }
        dij(1);/**< 计算1到其他点最短路径 */
        cin>>k;
        long long ans=0, pre=1;
        for(i=1;i<=k;i++){
            cin>>a[i];
            ans+=d[a[i]];/**< pre到a[i]的最短路径 */
            dij(a[i]);
            pre=a[i];
        }
        cout<<ans+d[n]<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>