题目描述

BESSIE准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘, 然后走回牛棚. BESSIE也不想跑得太远,所以她想走最短的路经. 农场上一共有M (1 <= M <= 10,000)条路, 每条路连接两个用1..N(1 <= N <= 1000)标号的地点. 更方便的是,如果X>Y,则地点X的高度大于地点Y的高度. 地点N是BESSIE的牛棚;地点1是池塘. 很快, BESSIE厌倦了一直走同一条路.所以她想走不同的路,更明确地讲,她想找出K (1 <= K <= 100)条不同的路经.为了避免过度劳累,她想使这K条路经为最短的K条路经. 请帮助BESSIE找出这K条最短路经的长度.你的程序需要读入农场的地图, 一些从X_i到Y_i 的路经和它们的长度(X_i, Y_i, D_i). 所有(X_i, Y_i, D_i)满足(1 <= Y_i < X_i; Y_i < X_i <= N, 1 <= D_i <= 1,000,000).

输入格式

第1行: 3个数: N, M, 和K

第 2..M+1行: 第 i+1 行包含3个数 X_i, Y_i, 和 D_i, 表示一条下坡的路.

输出格式

第1..K行: 第i行包含第i最短路经的长度,或-1如果这样的路经不存在.如果多条路经有同样的长度,请注意将这些长度逐一列出.


题意就是,求出给定图的前k短的n到1的路径,题目中的高度关系指明了图是有向的。

所以我们可以用A*来求k短路。

设计估价函数f。秉持f永远不大于真实值的原则,我们可以建个反图,把所有点到终点的最短路作为估计值,这样无论k等于多少时真实值都不会小于估计值。

然后跑A*,每次终点被取出时就输出此时的距离。注意如果取出次数不足k要用-1补足。

时间复杂度上限为O(K * (N+M)log(N+M)),但由于启发式,远远达不到这个程度。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define maxn 1001
#define maxm 100001
using namespace std; struct graph{
struct edge{
int to,dis,next;
edge(){}
edge(const int &_to,const int &_dis,const int &_next){ to=_to,dis=_dis,next=_next; }
}e[maxm];
int head[maxn],k;
inline void init(){ memset(head,-1,sizeof head); }
inline void add(const int &u,const int &v,const int &w){ e[k]=edge(v,w,head[u]); head[u]=k++; }
}a,b; int f[maxn];
bool vis[maxn];
int n,m,s,K; struct set_elmt{
int id,dis;
set_elmt(){}
set_elmt(const int &_dis,const int &_id){ id=_id,dis=_dis; }
bool operator<(const set_elmt &x)const{ return dis>x.dis; }
};//Dijkstra的优先级 struct node{
int id,dis;
node(){}
node(const int &_dis,const int &_id){ id=_id,dis=_dis; }
bool operator<(const node &x)const{ return dis+f[id]>x.dis+f[x.id]; }
};//A*的优先级 inline int read(){
register int x(0),f(1); register char c(getchar());
while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
} inline void dijkstra(){
memset(f,0x3f,sizeof f);
priority_queue<set_elmt> q;
q.push(set_elmt(0,1)),f[1]=0; while(q.size()){
int u=q.top().id; q.pop();
if(vis[u]) continue; vis[u]=true;
for(register int i=b.head[u];~i;i=b.e[i].next){
int v=b.e[i].to;
if(f[v]>f[u]+b.e[i].dis) f[v]=f[u]+b.e[i].dis,q.push(set_elmt(f[v],v));
}
}
} inline void astar(){
priority_queue<node> q;
q.push(node(0,n));
while(q.size()){
int u=q.top().id,w=q.top().dis; q.pop();
if(u==1){ printf("%d\n",w); if(--K==0) return; }
for(register int i=a.head[u];~i;i=a.e[i].next){
int v=a.e[i].to;
q.push(node(w+a.e[i].dis,v));
}
}
while(K--) puts("-1");
} int main(){
a.init(),b.init();
n=read(),m=read(),K=read();
for(register int i=1;i<=m;i++){
int u=read(),v=read(),w=read();
a.add(u,v,w),b.add(v,u,w);//b为反图
}
dijkstra(),astar();
return 0;
}

[Usaco2008 Mar]牛跑步的更多相关文章

  1. Bzoj 1598: [Usaco2008 Mar]牛跑步 dijkstra,堆,K短路,A*

    1598: [Usaco2008 Mar]牛跑步 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 427  Solved: 246[Submit][St ...

  2. bzoj 1598: [Usaco2008 Mar]牛跑步 [k短路 A*] [学习笔记]

    1598: [Usaco2008 Mar]牛跑步 题意:k短路 ~~貌似A*的题目除了x数码就是k短路~~ \[ f(x) = g(x) + h(x) \] \(g(x)\)为到达当前状态实际代价,\ ...

  3. BZOJ_1598_[Usaco2008 Mar]牛跑步_A*

    BZOJ_1598_[Usaco2008 Mar]牛跑步_A* Description BESSIE准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘, 然后走回牛棚. B ...

  4. bzoj 1598: [Usaco2008 Mar]牛跑步 -- 第k短路,A*

    1598: [Usaco2008 Mar]牛跑步 Time Limit: 10 Sec  Memory Limit: 162 MB Description BESSIE准备用从牛棚跑到池塘的方法来锻炼 ...

  5. K短路 (A*算法) [Usaco2008 Mar]牛跑步&[Sdoi2010]魔法猪学院

    A*属于搜索的一种,启发式搜索,即:每次搜索时加一个估价函数 这个算法可以用来解决K短路问题,常用的估价函数是:已经走过的距离+期望上最短的距离 通常和Dijkstra一起解决K短路 BZOJ1598 ...

  6. 【BZOJ】1598: [Usaco2008 Mar]牛跑步

    [题意]给定有向图,边严格从大编号指向小编号,求前k短路.n<=1000,m<=10000,k<=100. [算法]归并+拓扑排序||A*求第k短路 [题解]因为此题自带拓扑序的特殊 ...

  7. BZOJ1598: [Usaco2008 Mar]牛跑步

    传送门 K短路,普遍的算法是采用AStar求解,先建立反向边跑一遍dij,或者spfa什么的.跑出反向边的距离就可以看为估价函数中的$h()$.设$dist$为当前已经走过的距离,那么$f(node) ...

  8. bzoj:1598: [Usaco2008 Mar]牛跑步

    Description BESSIE准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘, 然后走回牛棚. BESSIE也不想跑得太远,所以她想走最短的路经. 农场上一共有M ...

  9. 【bzoj1598】【 [Usaco2008 Mar]牛跑步】启发式搜索思路+spfa

    (上不了p站我要死了,侵权度娘背锅) 最近复习搜索,先从启发式搜索来吧. 感觉启发式搜索这玩意挺玄学的,先从其思想入手,做一道经典的K短路. Description BESSIE准备用从牛棚跑到池塘的 ...

  10. bzoj 1598: [Usaco2008 Mar]牛跑步【A*K短路】

    A*K短路模板,详见https://blog.csdn.net/z_mendez/article/details/47057461 算法流程: 把有向图全建成反向边,跑一遍所有点到t的最短路记为dis ...

随机推荐

  1. css 05-CSS样式表的继承性和层叠性

    05-CSS样式表的继承性和层叠性 #本文重点 CSS的继承性 CSS的层叠性 计算权重 权重问题大总结 CSS样式表的冲突的总结 权重问题深入 同一个标签,携带了多个类名 !important标记 ...

  2. [日常摸鱼]poj1509Glass Beads-SAM

    QAQ学了好几天了-(我太傻啦) #include<cstdio> #include<cstring> #define rep(i,n) for(register int i= ...

  3. IIS本地部署局域网可随时访问的项目+mysql可局域网内访问

    开端口即可 或者以下 原理 在本机的IIS下创建一个网站,文件目录直接指向Web项目文件夹 步骤 1.项目的启动项目为web 2.在iis中创建一个新的网站(Work_TK_EIS) 文件目录为web ...

  4. 在开发板上显示英文字符和汉字--tiny6410

    程序字符需要改成gb2312.否则无法正常显示中文字符. main.c代码: #include <sys/types.h> #include <sys/stat.h> #inc ...

  5. Spring Cloud是什么鬼?

    研究了一段时间Spring Boot了准备向Spring Cloud进发,公司架构和项目也全面拥抱了Spring Cloud.在使用了一段时间后发现Spring Cloud从技术架构上降低了对大型系统 ...

  6. springboot容器启动顺序之@Configuration ContextRefreshedEvent事件初始化 ApplicationRunner

    笔者最近遇到一个问题 我们根据自己业务需要  需要首次启动springboot项目时 把数据库数据同步至本地缓存(比如ehcache)但有一个要求 在缓存未载入成功  不允许有流量打入 一开始我们使用 ...

  7. Linux 时间同步 04 ntp时间同步

    Linux 时间同步 04 ntp时间同步 目录 Linux 时间同步 04 ntp时间同步 安装ntp 配置与外部时间服务器进行时间同步的客户端主机 配置其他客户端与以上客户端主机时间同步 验证查看 ...

  8. spring boot(一):什么是spring boot

    什么是spring boot 官网说的很清晰 一.Overview Spring Boot makes it easy to create stand-alone, production-grade ...

  9. windows7 错误0xc00000ba;无法进入系统;

    事件背景:电脑windows7 错误0xc00000ba无法进系统:无法进入安全模式:无法进入最后一次正确配置: 事件处理:提示系统文件丢失,注册表异常:知乎有人提及更换WS2_32.DLL; 使用P ...

  10. centos 8.x系统配置chrony时间同步服务

    redhat/centos 7.x默认使用的时间同步服务为ntp服务,但是从redhat/centos 8开始在官方的仓库中移除了ntp软件,换成默认的chrony进行时间同步的服务,虽然也可以通过添 ...