C语言 堆优化d,codeforces(D. Navigation System)堆优化dijsktra算法

前天晚上的div2的一道题

大体意思是给你一个有向图,并给你一个导航,每次导航都会给你计算出最短路,但又给了你一个路径,必须按照给的这个路径走,每走到一个点,导航有可能都会重新计算从这个点到终点的最短路径,问导航计算的最少次数和最大次数是多少。

经大佬点播了一下,要反向建图,然后dijsktra求最后一个点到所有点的最短路,再正着走一遍即可

但敲完之后交上去超时了?

唉....真是孤陋寡闻.....1e5个点用我之前的朴素dijsktra轻轻松松超时

才知道,dijsktra有堆优化......

这里堆优化就是用一个优先队列存储一个点到下一个点的最短距离,用的时候直接O(1)出队即可

原题代码:

#include

#define ll long long

using namespace std;

struct qq

{

int to;

int w;

int next;

}q[200010];

struct qqq

{

int to;

int w;

int next;

}e[200010];

struct node

{

int val;

int num;

bool operator

return a.val

}

};

priority_queueque;

int head[200010],head2[200010],a[200010],dis[200010],book[200010],inf=99999999,n,m;

void dijsktra(int s)

{

for(int i=1;i<=n;i++)

{dis[i]=inf;}

dis[s]=0;

node e;

e.val=dis[s];e.num=s;

que.push(e);

while(!que.empty())

{

node u=que.top();

que.pop();

if(book[u.num]!=0)

{continue;}

book[u.num]=1;

for(int j=head[u.num];j!=-1;j=q[j].next)

{

if(dis[q[j].to]>dis[u.num]+q[j].w)

{

dis[q[j].to]=dis[u.num]+q[j].w;

if(book[q[j].to]==0)

{

node tmp;

tmp.num=q[j].to;

tmp.val=dis[q[j].to];

que.push(tmp);

}

}

}

}

}

int main()

{

scanf("%d %d",&n,&m);

for(int i=0;i<=n+1;i++)

{head[i]=-1;head2[i]=-1;}

int t1,t2;

for(int i=1;i<=m;i++)

{

scanf("%d %d",&t2,&t1);

//反向建图

q[i].to=t2;

q[i].w=1;

q[i].next=head[t1];

head[t1]=i;

//正向建图

e[i].to=t1;

e[i].w=1;

e[i].next=head2[t2];

head2[t2]=i;

}

int p;

scanf("%d",&p);

for(int i=0;i

{scanf("%d",&a[i]);}

int s=a[p-1];

dijsktra(s);

int l=0,r=0;

for(int i=1;i

{

if(dis[a[i]]>=dis[a[i-1]])

{l++;r++;}

else

{

int d=a[i-1];

for(int j=head2[d];j!=-1;j=e[j].next)

{

if(dis[e[j].to]<=dis[a[i]]&&e[j].to!=a[i])

{r++;break;}

}

}

}

cout<

return 0;

}

123

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值