【分层图最短路】P4568 [JLOI2011]飞行路线
发布日期:2021-05-06 16:51:18 浏览次数:10 分类:技术文章

本文共 1389 字,大约阅读时间需要 4 分钟。

将免费乘坐的机会看做两个层之间的边,对于读入的每天一条边,都再k层内建边,以及跨层建边

然后就可以跑dijkstra

注意:最后的答案可能不在dis[t+k*n]上,因为最优解可能没有使用k次免费的机会,所以需要统计一下每层t位置的dis值,取最小即可

 

代码

#include
using namespace std;const int maxn=5e6+5;int n,m,k,s,t;int dis[maxn],vis[maxn],head[maxn],tot;struct edge{ int to,nxt,v;}e[maxn<<1];int read(){ char cc=getchar(); int x=0,f=1; while((cc<'0' || cc>'9') && cc!='-') cc=getchar(); if(cc=='-') f=-1,cc=getchar(); while(cc>='0' && cc<='9') { x=x*10+cc-'0'; cc=getchar(); } return x*f;}void add(int x,int y,int z){ e[++tot].nxt=head[x]; e[tot].to=y; e[tot].v=z; head[x]=tot;}priority_queue
,vector
> ,greater
> > q;void dijkstra(int x){ memset(dis,0x3f,sizeof(dis)); dis[x]=0; q.push(make_pair(0,s)); while(!q.empty()) { int u=q.top().second; q.pop(); if(!vis[u]) { vis[u]=1; for(int i=head[u];i;i=e[i].nxt) { int to=e[i].to; int v=e[i].v; if(dis[to]>dis[u]+v) { dis[to]=dis[u]+v; q.push(make_pair(dis[to],to)); } } } }}int main(){ freopen("a.in","r",stdin); freopen("a.out","w",stdout); n=read(); m=read(); k=read(); s=read(); t=read(); for(int i=1;i<=m;i++) { int x,y,z; x=read(); y=read(); z=read(); add(x,y,z); add(y,x,z); for(int j=1;j<=k;j++) { add(x+n*(j-1),y+n*j,0); add(y+n*(j-1),x+n*j,0); add(x+j*n,y+n*j,z); add(y+j*n,x+n*j,z); } } dijkstra(s); int ans=0x3f3f3f3f; for(int i=0;i<=k;i++) ans=min(ans,dis[t+i*n]); printf("%d\n",ans); return 0;}

 

上一篇:【最短路】P4408 [NOI2003]逃学的小孩
下一篇:【拓扑序】P1038 神经网络

发表评论

最新留言

不错!
[***.144.177.141]2025年03月15日 17时55分03秒