K短路 (A*算法) [Usaco2008 Mar]牛跑步&[Sdoi2010]魔法猪学院
A*属于搜索的一种,启发式搜索,即:每次搜索时加一个估价函数
这个算法可以用来解决K短路问题,常用的估价函数是:已经走过的距离+期望上最短的距离
通常和Dijkstra一起解决K短路
BZOJ1598:牛跑步
求前K短路
因为A*算法我们每次用来向外拓展的是估价函数最小的点,那么,我们必定能够得到,第一个到达n的是最短路。(Dijkstra的贪心,可证)
那么,我们思考一下,第二个到达n的就是次短路!
由此观之:第K个到达的就是K短路
因此,A*算法可以用来解决K短路问题
附上代码:
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <iostream>
#include <map>
using namespace std;
#define N 10005
#define ll long long
struct node
{
int to,next,val;
}e[N*10],E[N*10];
int head[N],cnt,cnt1,n,m,K,vis[N],head1[N];
int dis[N];
void add(int x,int y,int z)
{
e[cnt].to=y;
e[cnt].next=head[x];
e[cnt].val=z;
head[x]=cnt++;
}
void add1(int x,int y,int z)
{
E[cnt1].to=y;
E[cnt1].next=head1[x];
E[cnt1].val=z;
head1[x]=cnt1++;
}
priority_queue<pair<int ,int > >q;
void Dijkstra()
{
memset(dis,0x3f,sizeof(dis));
dis[n]=0;
q.push(make_pair(0,n));
while(!q.empty())
{
int x=q.top().second;q.pop();
if(vis[x])continue;
vis[x]=1;
for(int i=head1[x];i!=-1;i=E[i].next)
{
int to1=E[i].to;
if(dis[to1]>dis[x]+E[i].val)
{
dis[to1]=dis[x]+E[i].val;
q.push(make_pair(-dis[to1],to1));
}
}
}
}
void Astar(int s)
{
q.push(make_pair(-dis[s],s));
while(!q.empty())
{
int d=q.top().first;int x=q.top().second;q.pop();
if(x==n)
{
K--;
printf("%d\n",-d);
if(!K)return ;
}
for(int i=head[x];i!=-1;i=e[i].next)
{
int to1=e[i].to;
q.push(make_pair(d+dis[x]-e[i].val-dis[to1],to1));
}
}
}
int main()
{
memset(head1,-1,sizeof(head1));
memset(head,-1,sizeof(head));
scanf("%d%d%d",&n,&m,&K);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(y,x,z);
add1(x,y,z);
}
Dijkstra();
Astar(1);
while(K--)puts("-1");
return 0;
}
1975: [Sdoi2010]魔法猪学院
这个贪心贪的很显然,为了尽可能的多,自然是选择前K短路
那么,同样,我们用Dijkstra的贪心方法求n的前K短路
但是这种方法实际的时间复杂度不是很对,理论上可以过很多题。这道题BZOJ可以过,但是洛谷上过不去
附上不完美的代码:
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <iostream>
#include <map>
using namespace std;
#define N 5005
#define ll long long
struct node
{
int to,next;
double val;
}e[200005],E[200005];
int head[N],cnt,cnt1,n,m,vis[N],head1[N],ans;
double dis[N],K;
void add(int x,int y,double z)
{
e[cnt].to=y;
e[cnt].next=head[x];
e[cnt].val=z;
head[x]=cnt++;
}
void add1(int x,int y,double z)
{
E[cnt1].to=y;
E[cnt1].next=head1[x];
E[cnt1].val=z;
head1[x]=cnt1++;
}
priority_queue<pair<double ,int > >q;
void Dijkstra()
{
for(int i=0;i<N;i++)dis[i]=1e9;
dis[n]=0;
q.push(make_pair(0,n));
while(!q.empty())
{
int x=q.top().second;q.pop();
if(vis[x])continue;
vis[x]=1;
for(int i=head1[x];i!=-1;i=E[i].next)
{
int to1=E[i].to;
if(dis[to1]>dis[x]+E[i].val)
{
dis[to1]=dis[x]+E[i].val;
q.push(make_pair(-dis[to1],to1));
}
}
}
}
void Astar(int s)
{
q.push(make_pair(-dis[s],s));
while(!q.empty())
{
double d=q.top().first;int x=q.top().second;q.pop();
if(x==n)
{
if(K+d<0-1e-9)return ;
K+=d;
ans++;
}
for(int i=head[x];i!=-1;i=e[i].next)
{
int to1=e[i].to;
q.push(make_pair(d+dis[x]-e[i].val-dis[to1],to1));
}
}
}
int main()
{
memset(head1,-1,sizeof(head1));
memset(head,-1,sizeof(head));
scanf("%d%d%lf",&n,&m,&K);
for(int i=1;i<=m;i++)
{
int x,y;double z;
scanf("%d%d%lf",&x,&y,&z);
add(x,y,z);
add1(y,x,z);
}
Dijkstra();
Astar(1);
printf("%d\n",ans);
return 0;
}
正解是用可持久化可并堆+A*算法,挖坑待填
K短路 (A*算法) [Usaco2008 Mar]牛跑步&[Sdoi2010]魔法猪学院的更多相关文章
- bzoj 1598: [Usaco2008 Mar]牛跑步 [k短路 A*] [学习笔记]
1598: [Usaco2008 Mar]牛跑步 题意:k短路 ~~貌似A*的题目除了x数码就是k短路~~ \[ f(x) = g(x) + h(x) \] \(g(x)\)为到达当前状态实际代价,\ ...
- bzoj 1598: [Usaco2008 Mar]牛跑步 -- 第k短路,A*
1598: [Usaco2008 Mar]牛跑步 Time Limit: 10 Sec Memory Limit: 162 MB Description BESSIE准备用从牛棚跑到池塘的方法来锻炼 ...
- Bzoj 1598: [Usaco2008 Mar]牛跑步 dijkstra,堆,K短路,A*
1598: [Usaco2008 Mar]牛跑步 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 427 Solved: 246[Submit][St ...
- BZOJ_1598_[Usaco2008 Mar]牛跑步_A*
BZOJ_1598_[Usaco2008 Mar]牛跑步_A* Description BESSIE准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘, 然后走回牛棚. B ...
- bzoj1975: [Sdoi2010]魔法猪学院【k短路&A*算法】
1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 2446 Solved: 770[Submit][Statu ...
- [BZOJ1975][SDOI2010]魔法猪学院(k短路,A*)
1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 2748 Solved: 883[Submit][Statu ...
- Bzoj 1975: [Sdoi2010]魔法猪学院 dijkstra,堆,A*,K短路
1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1357 Solved: 446[Submit][Statu ...
- [SDOI2010]魔法猪学院(A*,最短路)
[SDOI2010]魔法猪学院(luogu) Description 题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig ...
- bzoj 1598: [Usaco2008 Mar]牛跑步【A*K短路】
A*K短路模板,详见https://blog.csdn.net/z_mendez/article/details/47057461 算法流程: 把有向图全建成反向边,跑一遍所有点到t的最短路记为dis ...
随机推荐
- dsd
nodeName属性 nodeName属性规定节点的名称 nodeName是只读的 元素节点的nodeName与属性名相同 属性节点的nodeName与属性名相同 文本节点nodeName始终是#te ...
- JavaScript遍历XML总结
1:读取服务器端xml(注意不同浏览器版本的区别),使用XML可以增强系统的扩展性,只用修改XML就可以实现增加减少功能的目的. function loadXMLDoc1(dname){ if ...
- 使用ASP.NET SignalR实现一个简单的聊天室
前言 距离我写上一篇博客已经又过了一年半载了,时间过得很快,一眨眼,就把人变得沧桑了许多.青春是短暂的,知识是无限的.要用短暂的青春,去学无穷无尽的知识,及时当勉励,岁月不待人.今天写个随笔小结记录一 ...
- java线程之线程同步
本篇由于涉及多线程操作,所以线程是使用实现Runnable接口来创建的. 在上篇所示线程任务中,我们不难发现,是存在三步操作的: 第一:打印语句: 第二:计算sum=sum-1: 第三:线程休眠. 那 ...
- 程序员DD 《Spring boot教程系列》补充
最近在跟着程序员DD的Spring boot教程系列学习Spring boot,由于年代原因,Spring boot已经发生了一些变化,所以在这里进行一些补充. 补充的知识大多来自评论区,百度,Sta ...
- Flask入门之Bootstrap介绍使用和Flask-Nav快速导航栏
一.Bootstrap Bootstrap,来自 Twitter,是目前最受欢迎的前端框架. Python中,同样可以使用Bootstrap. 1. 导入Bootstrap库 from flask_b ...
- 原生 JavaScript 实现扫雷
学习了这么长时间的 JS,不能光看不练,于是就写了个小游戏练习一下.因为自己还是个菜鸟,所以有错误的话还请各位大佬多多指点,谢谢啦~ 如果感兴趣的话可以试试:Demo 项目地址:game-mineSw ...
- PAT1040:Longest Symmetric String
1040. Longest Symmetric String (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, ...
- Cookie与 Session使用详解
Cookie概念 在浏览某些 网站 时,这些网站会把 一些数据存在 客户端 , 用于使用网站 等跟踪用户,实现用户自定义 功能. 是否设置过期时间: 如果不设置 过期时间,则表示这个 Cookie生命 ...
- MySQL 数据库 Query 的优化
理解MySQL的Query Optimizer MySQL Optimizer是一个专门负责优化SELECT 语句的优化器模块,它主要的功能就是通过计算分析系统中收集的各种统计信息,为客户端请求的Qu ...