题目描述

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. c++日常小问题

    语法解析问题. 当给一个变量构造函数传递一个临时变量,而不是命名的变量,c++编译器会将其解析为函数声明,而不是类型对象的定义. class hello { void operator()() { s ...

  2. pandas的学习3-设置值

    import pandas as pd import numpy as np # 我们可以根据自己的需求, 用 pandas 进行更改数据里面的值, 或者加上一些空的,或者有数值的列. # 首先建立了 ...

  3. [TSCTF-J] relax

    [TSCTF-J] relax 1.源码审计 利用扫描器可以扫到robots.txt 进入发现三个文件 flag.php heicore.php relax.php 我们只能进入relax.php 发 ...

  4. yii\filters\AccessControl 访问权限控制

    Class yii\filters\AccessControl 所有类 | 属性 | 方法   继承 yii\filters\AccessControl » yii\base\ActionFilter ...

  5. RabbiMQ重新安装会遇到的错误-SpiritMark

    这里只做安装过程中遇到错误的介绍,不喜勿喷,如果对您有帮助右上角关注一下,是对我最大的肯定 重新安装的注意事项: 先卸载RabbitMQ,后卸载Erlang RabbitMQ卸载,选择uninstal ...

  6. Codis集群相关

    在大数据高并发场景下,单个 Redis 实例往往会显得捉襟见肘.首先体现在内存上,单个 Redis 的内存不宜过大,内存太大会导致 rdb 文件过大,进一步导致主从同步时全量同步时间过长,在实例重启恢 ...

  7. openstack高可用集群21-生产环境高可用openstack集群部署记录

    第一篇 集群概述 keepalived + haproxy +Rabbitmq集群+MariaDB Galera高可用集群   部署openstack时使用单个控制节点是非常危险的,这样就意味着单个节 ...

  8. python scipy 求解简单线性方程组和fmin求函数最小值

    ###这是一个利用内置函数求最小值#####def func(x): return x ** 2 - 2 *x x = 1 func(x) opt.fmin(func ,x)## 用scipy求解线性 ...

  9. ASP.NET Core WebAPI实现本地化多语言(单资源文件)

    在Startup ConfigureServices 注册本地化所需要的服务AddLocalization和 Configure<RequestLocalizationOptions> p ...

  10. 【终极版】利用阿里云云解析API实现动态域名解析(ddns),搭建私有服务器【含可执行文件和源码】

    前言:懒人可以直接往下看,有代码和全部资源可以下载.此文章是先前文章的定时版,主要是添加了定时执行的功能,并且将代码中的配置项放置到了app.config文件中,方便不懂开发的朋友修改使用.未经许可请 ...