题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2763

分层图两种方法的练习。

1.把图分成k+1层,本层去上面一层的边免费。但空间时间都不算优秀。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
const int N=1e4+5,M=5e4+5,K=15;
int n,m,k,head[N*K],xnt,s,t;
ll dis[N*K],ans=0x7fffffff;
bool vis[N*K];
struct Edge{int next,to,w;Edge(int n=0,int t=0,int w=0):next(n),to(t),w(w) {}
}edge[M*K<<2];
void add(int x,int y,int z)
{for(int fx=0;fx<=k*n;fx+=n){edge[++xnt]=Edge(head[x+fx],y+fx,z);head[x+fx]=xnt;if(fx<k*n)edge[++xnt]=Edge(head[x+fx],y+fx+n,0),head[x+fx]=xnt;}
}
void dj()
{memset(dis,1,sizeof dis);dis[s]=0;priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > > q;q.push(make_pair(0,s));while(q.size()){int u=q.top().second;q.pop();while(vis[u]&&q.size())u=q.top().second,q.pop();if(vis[u])break;vis[u]=1;for(int i=head[u],v;i;i=edge[i].next)if(dis[v=edge[i].to]>dis[u]+edge[i].w){dis[v]=dis[u]+edge[i].w;q.push(make_pair(dis[v],v));}}
}
int main()
{scanf("%d%d%d%d%d",&n,&m,&k,&s,&t);int x,y,z;for(int i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&z);add(x,y,z);add(y,x,z);}dj();for(int fx=0;fx<=k*n;fx+=n)ans=min(ans,dis[t+fx]);printf("%lld",ans);return 0;
}

View Code

2.设计dp状态,套在最短路上。就不用建边,从而省空间。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
const int N=1e4+5,M=5e4+5,K=15;
int n,m,k,s,t,head[N],xnt;
ll ans=0x7fffffff,dp[N][K];
bool vis[N][K];
struct Edge{int next,to,w;Edge(int n=0,int t=0,int w=0):next(n),to(t),w(w) {}
}edge[M<<1];
void add(int x,int y,int z)
{edge[++xnt]=Edge(head[x],y,z);head[x]=xnt;edge[++xnt]=Edge(head[y],x,z);head[y]=xnt;
}
void spfa()
{memset(dp,1,sizeof dp);dp[s][0]=0;queue<pair<int,int> > q;q.push(make_pair(s,0));vis[s][0]=1;while(q.size()){int u=q.front().first,d=q.front().second;q.pop();vis[u][d]=0;for(int i=head[u],v;i;i=edge[i].next){if(dp[v=edge[i].to][d]>dp[u][d]+edge[i].w){dp[v][d]=dp[u][d]+edge[i].w;if(!vis[v][d])vis[v][d]=1,q.push(make_pair(v,d));}if(d<k&&dp[v][d+1]>dp[u][d]){dp[v][d+1]=dp[u][d];if(!vis[v][d+1])vis[v][d+1]=1,q.push(make_pair(v,d+1));}}}
}
int main()
{scanf("%d%d%d%d%d",&n,&m,&k,&s,&t);int x,y,z;for(int i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&z);add(x,y,z);}spfa();for(int i=0;i<=k;i++)ans=min(ans,dp[t][i]);printf("%lld",ans);return 0;
}

View Code

  上面的代码巨慢!用dj的话可以及时推出,所以会非常快!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
const int N=1e4+5,M=5e4+5,K=15;
int n,m,k,s,t,head[N],xnt;
ll ans=0x7fffffff,dp[N][K];
bool vis[N][K];
struct Edge{int next,to,w;Edge(int n=0,int t=0,int w=0):next(n),to(t),w(w) {}
}edge[M<<1];
struct Node{ll dis;int v,c;Node(ll d,int a,int b):dis(d),v(a),c(b) {}bool operator<(const Node k)const{return dis>k.dis;}
};
void add(int x,int y,int z)
{edge[++xnt]=Edge(head[x],y,z);head[x]=xnt;edge[++xnt]=Edge(head[y],x,z);head[y]=xnt;
}
void dj()
{memset(dp,1,sizeof dp);dp[s][0]=0;priority_queue<Node> q;q.push(Node(0,s,0));while(q.size()){ll x=q.top().dis,u=q.top().v,d=q.top().c;q.pop();while(vis[u][d]&&q.size())x=q.top().dis,u=q.top().v,d=q.top().c,q.pop();if(vis[u][d])break;vis[u][d]=1;if(u==t){ans=x;return;}for(int i=head[u],v;i;i=edge[i].next){if(dp[v=edge[i].to][d]>x+edge[i].w){dp[v][d]=x+edge[i].w;q.push(Node(dp[v][d],v,d));}if(d<k&&dp[v][d+1]>x){dp[v][d+1]=x;q.push(Node(dp[v][d+1],v,d+1));}}}
}
int main()
{scanf("%d%d%d%d%d",&n,&m,&k,&s,&t);int x,y,z;for(int i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&z);add(x,y,z);}dj();printf("%lld",ans);return 0;
}

转载于:https://www.cnblogs.com/Narh/p/9216751.html

bzoj 2763 [JLOI2011]飞行路线——分层图相关推荐

  1. 洛谷 - P4568 [JLOI2011]飞行路线(分层图最短路)

    题目链接:点击查看 题目大意:给出一张图,每条边都有权值,现在要求从点st到达点ed,沿途中可以让k条边的边权免费,现在求最短路 题目分析:分层图经典模板问题,直接套板子就行了,最后记得对于数组d的每 ...

  2. BZOJ 2763: [JLOI2011]飞行路线 spfa dp

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=2763 题解: d[x][kk]表示从s到x用了kk次免费机会的最少花费. 代码: #in ...

  3. BZOJ 2763: [JLOI2011]飞行路线 【SPFA】

    Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格.Al ...

  4. BZOJ 2763[JLOI2011]飞行路线 - 最短路

    描述 给出一个无向图, 出发地$s$和目的地$t$, 让你求出不计算 任意$K$条边权值 的最短路 题解 刚开始我是用记忆化搜索记录状态$F_{i, k}$, 表示从出发地出发 到第$i$个城市, 还 ...

  5. 【Dijsktra priority!】分层图

    这里先直接上一个题解,下午应该会有自己的打法! /* 首先看一个问题: 在你的强力援助下,PCY 成功完成了之前的所有任务,他觉得,现在正是出去浪的大好时光.于是,他来到高速公路上,找到一辆摩的前往几 ...

  6. bzoj2763 [JLOI2011]飞行路线

    2763: [JLOI2011]飞行路线 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 3216  Solved: 1230 [Submit][St ...

  7. 洛谷 P4568 [JLOI2011] 飞行路线(分层图最短路)

    [JLOI2011] 飞行路线 题目描述 Alice 和 Bob 现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在 n n n 个城市设有业务,设这些城市分别标记为 0 0 0 到 ...

  8. 【HYSBZ - 2763 】飞行路线 (分层图最短路,最短路dp)

    题干: Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价 ...

  9. Bzoj 2662: [BeiJing wc2012]冻结 dijkstra,堆,分层图,最短路

    2662: [BeiJing wc2012]冻结 Time Limit: 3 Sec  Memory Limit: 128 MB Submit: 647  Solved: 348 [Submit][S ...

最新文章

  1. 关于上传文件的跨域问题
  2. dede5.7 GBK 在php5.4环境下 后台编辑器无法显示文章内容
  3. C 函数别名简单记录
  4. MyEclipse6.0下代码提示(alt+/)无法使用的解决方法
  5. 分布式事务?No, 最终一致性
  6. 九度 1474:矩阵幂(二分法)
  7. linux连接u盘是提示usb驱动错误,U盘提示无法访问,由于I/O设备错误,无法运行此项请求3种完美解决办法...
  8. Heritrix 3.1.0 源码解析(二十八)
  9. picGo图片上传到码云失败,报错404-{“message”:“Branch”}的解决方法
  10. [转自他人]一款好用的软件安装管理器
  11. vm虚拟机安装lede旁路由_Vmware虚拟机安装LEDE实现软路由openwrt
  12. h5 字体加粗_div css布局对文字字体加粗样式设置
  13. 私藏的自媒体图片素材网站,一键下载,免费使用
  14. 安装 Swoole教程
  15. d2lzh_pytorch安装
  16. 利用RunLoop空闲时间执行预缓存任务
  17. 这样做数据可视化驾驶舱,高端大气,一目了然,领导不点赞都难
  18. 分布式中间件──断路器
  19. 开发巴西市场全攻略,外贸人收藏
  20. Python excel xlwings+QT 考勤表开发 -【Python Office开发基础培训】 拆分合并文件

热门文章

  1. java transaction cn_GitHub - cnzebra/tcc-transaction: tcc-transaction是TCC型事务java实现
  2. 中立时滞matlab,中立型时滞系统的稳定性改进判据
  3. const int *p说明不能修改_C语言关键字const和指针结合的使用
  4. [CF446C]DZY Loves Fibonacci Numbers
  5. OpenShift helm的安装
  6. maven配置国内阿里云镜像
  7. ASP.NET里创建Microsoft Word文档
  8. php的autoload机制
  9. int, float, double之间不得不说的故事
  10. mysql 之 一个库中所有表复制到另一个数据库中的方法和工具