图论——分层图最短路
概述
分层图最短路,如:有
其中
概念理解:分层图最短路往往是与
例题
例
简单来说,本题是在无向图上求出一条从
可以仿照前面所说的方法,用
显然,我们刚才设计的状态转移是有后效性的(因为本题是按照动态规划的思想解决的,动态规划对状态空间的遍历构成一张有向无环图。注意一定是有向无环图!遍历顺序就是该有向无环图的一个拓扑序。 有向无向图中的节点对应问题中的“状态”,图中的边对应状态之间的“转移”,转移的选取就是动态规划中的“决策”。 在本题中,比如有三个点
从最短路径问题的角度去理解,图中的节点也不仅限于“整数编号”,可以扩展到二维,用二元组
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,p,k;
const int N=1000000+10,M=10000000+10;
int head[N],to[M],nxt[M],cnt,w[M],dis[N];
struct node{
int val,pos;
bool operator >(const node &x)const{
return val>x.val;
}
};
void add(int u,int v,int f){
to[++cnt]=v;
w[cnt]=f;
nxt[cnt]=head[u];
head[u]=cnt;
return;
}
priority_queue<node,vector<node>,greater<node> >q;
bool v[N];
void dijkstra(){
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
q.push(node{0,1});
while(!q.empty()){
node t=q.top();q.pop();
if(v[t.pos])continue;
v[t.pos]=1;
for(int i=head[t.pos];i;i=nxt[i]){
int v=to[i],z=max(dis[t.pos],w[i]);
if(dis[v]>z){
dis[v]=z;
q.push(node{dis[v],v});
}
}
}
return;
}
signed main(){
scanf("%lld %lld %lld",&n,&p,&k);
for(int i=1,x,y,z;i<=p;i++){
scanf("%lld %lld %lld",&x,&y,&z);
add(x,y,z);add(y,x,z);
for(int j=1;j<=k;j++){
add(x+(j-1)*n,y+j*n,0);
add(y+(j-1)*n,x+j*n,0);
add(x+j*n,y+j*n,z);
add(y+j*n,x+j*n,z);
}
}
dijkstra();
int ans=1e18;
for(int i=0;i<=k;i++){
ans=min(ans,dis[n+i*n]);
}
if(ans==1e18)printf("-1\n");
else printf("%lld\n",ans);
return 0;
}
例
由于购买机票不需要花钱,所以肯定不会多次重复乘坐同样的航线或者多次访问到同一个城市。如果
代码如下
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+50,M=2200050;
int head[N*12],cnt,nxt[M],to[M],w[M],n,m,k,s,t,dis[N*12];
void add(int u,int v,int f)
{
to[++cnt]=v;
nxt[cnt]=head[u];
w[cnt]=f;
head[u]=cnt;
}
struct node
{
int val,pos;
bool operator >(const node &x)const{
return val>x.val;
}
};
priority_queue<node,vector<node>,greater<node> >q;
bool b[N*12];
void dij()
{
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
q.push(node{dis[s],s});
while(!q.empty())
{
node t=q.top();q.pop();
if(b[t.pos])continue;
b[t.pos]=1;
for(int i=head[t.pos];i;i=nxt[i])
{
int v=to[i];
if(dis[v]>dis[t.pos]+w[i])
{
dis[v]=dis[t.pos]+w[i];
q.push(node{dis[v],v});
}
}
}
return;
}
int main()
{
scanf("%d %d %d",&n,&m,&k);
scanf("%d %d",&s,&t);
for(int i=1,u,v,w;i<=m;i++)
{
scanf("%d %d %d",&u,&v,&w);
add(u,v,w);add(v,u,w);
for(int j=1;j<=k;j++)
{
add(u+j*n,v+j*n,w);
add(v+j*n,u+j*n,w);
add(u+j*n-n,v+j*n,0);
add(v+j*n-n,u+j*n,0);
}
}
dij();
int ans=0x3f3f3f3f;
for(int j=0;j<=k;j++)
if(dis[t+j*n]<ans)
ans=dis[t+j*n];
printf("%d\n",ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具