k短路(A*)
http://poj.org/problem?id=2449
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn=1e3+; /**
求第K短的算法基于BFS搜索,当终点出队K次时,所走的总距离就是第K短路,
不过这样那些不该走的路会被反复的走,造成许多空间时间浪费,这时候就要用到启发式的A*搜索
**/ ///from s to t
///opp:from t to s struct node
{
int d,len;
node *next;
}*e[maxn],*oppe[maxn]; ///h:from this point to destination(predict must:predict<actual)
///g:from source to this point(actual)
int h[maxn],unreach; struct rec
{
int d,dist;
bool operator<(const rec &b) const
{
return b.dist<dist;
}
};
priority_queue<rec>st; struct noa
{
int d,dist,pre;
bool operator<(const noa &b) const
{
if (b.pre==pre)
return b.dist<dist;
return b.pre<pre;
}
};
priority_queue<noa>ast; bool vis[maxn];
int s,t,ind,ci[maxn]; int astar()
{
int d,dist;
node *p;
///多组数据时需要
// while (!ast.empty())
// ast.pop();
if (h[s]!=unreach)
ast.push({s,,h[s]});
while (!ast.empty())
{
d=ast.top().d;
dist=ast.top().dist;
ast.pop();///!
ci[d]++;
if (ci[d]==ind && d==t)
return dist;///而不是ast.top().dist
///优化
if (ci[d]>ind)
continue; p=e[d];
while (p)
{
if (h[p->d]!=unreach)
///aster
ast.push({p->d,dist+p->len,dist+p->len+h[p->d]});
///just dijkstra
// ast.push({p->d,dist+p->len,dist+p->len});
p=p->next;
}
}
return -;
} void opp_dijkstra()
{
int d,dd;
node *p;
memset(h,0x7f,sizeof(h));
unreach=h[];
h[t]=;
st.push({t,});
while ()
{
while (!st.empty() && vis[st.top().d])
st.pop();
if (st.empty())
break;
d=st.top().d;
st.pop();
vis[d]=;
p=oppe[d];///
while (p)
{
dd=p->d;
if (h[dd]>h[d]+p->len)
{
h[dd]=h[d]+p->len;
st.push({dd,h[dd]});
}
p=p->next;
}
}
} int main()
{
int a,b,c,n,m,i;
node *p;
scanf("%d%d",&n,&m);
for (i=;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
p=new node();
p->d=b;
p->len=c;
p->next=e[a];
e[a]=p; p=new node();
p->d=a;
p->len=c;
p->next=oppe[b];
oppe[b]=p;
}
scanf("%d%d%d",&s,&t,&ind);
///!!!
if (s==t)
ind++;
// ///shortest path
// scanf("%d%d",&s,&t);
// ind=1;
opp_dijkstra();
printf("%d",astar());
return ;
}
/*
2 2
1 2 1
2 1 1
1 1 1 3 3
1 2 1
2 3 2
3 2 1
1 1 1 3 3
1 2 1
2 3 2
3 1 3
1 1 2 3 1
1 2 3
1 3 1 3 2
1 2 10
2 3 2
1 3 1 3 2
1 2 10
2 3 2
1 3 2 4 4
1 3 2
3 2 5
1 4 3
4 2 1
1 2 2 x
4 4
1 2 100000
2 3 1
3 2 1
3 4 100000
1 4 1000 3 4
1 2 1
2 1 2
2 3 1
3 2 1
2 3 5 3 3
1 2 1000
1 3 1
3 2 1
1 2 1 */
https://www.luogu.org/problemnew/show/P2483
68分……
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn=5e3+; struct node
{
int d;
double len;
node *next;
}*e[maxn],*oppe[maxn]; ///h:from this point to destination(predict must:predict<actual)
///g:from source to this point(actual)
double h[maxn],unreach;
double tot; struct rec
{
int d;
double dist;
bool operator<(const rec &b) const
{
return b.dist<dist;
}
};
priority_queue<rec>st; struct noa
{
int d,g;
double dist,pre;
bool operator<(const noa &b) const
{
if (b.pre==pre)
return b.dist<dist;
return b.pre<pre;
}
};
priority_queue<noa>ast; bool vis[maxn];
int s,t,ind,re,n,m;
int ci[maxn]; void aster()
{
int d,dd,g;
double dist,ddist;
node *p;
ind=tot/h[];///限制次数 if (h[s]!=unreach)
ast.push({s,,,h[s]});
while (!ast.empty())
{
d=ast.top().d;
dist=ast.top().dist;
g=ast.top().g;
ast.pop();///!
ci[d]++;
if (d==t)
{
if (dist>tot)
return;
tot-=dist;
re++;
ind=re+tot/dist;///限制次数,优化
continue; ///这题的坑爹地方:到达终点,就不能再走了
} p=e[d];
while (p)
{
dd=p->d;
ddist=dist+p->len;
if (h[dd]!=unreach && g!=m && ci[dd]<ind && ddist<=tot)
ast.push({dd,g+,ddist,ddist+h[p->d]});
p=p->next;
}
}
} void opp_dijkstra()
{
int d,dd,i;
node *p;
unreach=1.0e11;
for (i=;i<=n;i++)
h[i]=unreach; h[t]=;
st.push({t,});
while ()
{
while (!st.empty() && vis[st.top().d])
st.pop();
if (st.empty())
break;
d=st.top().d;
st.pop();
vis[d]=;
p=oppe[d];///
while (p)
{
dd=p->d;
if (h[dd]>h[d]+p->len)
{
h[dd]=h[d]+p->len;
st.push({dd,h[dd]});
}
p=p->next;
}
}
} int main()
{
int a,b,i;
double c;
node *p,*pp;
scanf("%d%d",&n,&m);
scanf("%lf",&tot);
for (i=;i<=m;i++)
{
scanf("%d%d%lf",&a,&b,&c);
p=new node();
p->d=b;
p->len=c;
p->next=e[a];
e[a]=p; p=new node();
p->d=a;
p->len=c;
p->next=oppe[b];
oppe[b]=p;
}
s=,t=n;
opp_dijkstra();
///lower the memory
for (i=;i<=n;i++)
{
p=oppe[i];
while (p)
{
pp=p;
p=p->next;
free(pp);
}
}
aster();
printf("%d",re);
return ;
}
k短路(A*)的更多相关文章
- POJ 2449 Remmarguts' Date --K短路
题意就是要求第K短的路的长度(S->T). 对于K短路,朴素想法是bfs,使用优先队列从源点s进行bfs,当第K次遍历到T的时候,就是K短路的长度. 但是这种方法效率太低,会扩展出很多状态,所以 ...
- POJ 2449Remmarguts' Date K短路模板 SPFA+A*
K短路模板,A*+SPFA求K短路.A*中h的求法为在反图中做SPFA,求出到T点的最短路,极为估价函数h(这里不再是估价,而是准确值),然后跑A*,从S点开始(此时为最短路),然后把与S点能达到的点 ...
- BZOJ-1975 魔法猪学院 K短路 (A*+SPFA)
1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1323 Solved: 433 [Submit][Statu ...
- 【POJ】2449 Remmarguts' Date(k短路)
http://poj.org/problem?id=2449 不会.. 百度学习.. 恩. k短路不难理解的. 结合了a_star的思想.每动一次进行一次估价,然后找最小的(此时的最短路)然后累计到k ...
- poj 2449 Remmarguts' Date K短路+A*
题目链接:http://poj.org/problem?id=2449 "Good man never makes girls wait or breaks an appointment!& ...
- 第k短路
poj 2449 模板题 A*+spfa #include<iostream> #include<cstdio> #include<cstring> #inclu ...
- poj 2449(A*求第K短路)
题目链接:http://poj.org/problem?id=2449 思路:我们可以定义g[x]为源点到当前点的距离,h[x]为当前点到目标节点的最短距离,显然有h[x]<=h*[x](h*[ ...
- K短路
K短路 用dijsktra+A*启发式搜索当点v第K次出堆的时候,这时候求得的路径是k短路.A*算法有一个启发式函数f(p)=g(p)+h(p), 即评估函数=当前值+当前位置到终点的最短距离g(p) ...
- poj 2449 Remmarguts' Date(第K短路问题 Dijkstra+A*)
http://poj.org/problem?id=2449 Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536K Total Subm ...
- bzoj 1975 [Sdoi2010]魔法猪学院(k短路)
题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的:元素与 ...
随机推荐
- CentOS7学习
1.为什么学linux? linux开源免费,系统稳定,多用户的操作系统. linux有许多版本,各个版本之间的不同点大概分三种? > 内核不同 > 集成不同的应用 > 定制不同的图 ...
- 二、kubernetes环境搭建
主要内容 1.环境准备(2主机) 2.安装流程 3.问题分析 4.总结 环境配置(2主机) 系统:CentOS 7.3 x64 网络:局域网(VPC) 主机: master:172.16.0.17 m ...
- tomcat 和jboss区别
参考http://blog.csdn.net/sz_bdqn/article/details/6762175
- Lodop打印设计(PRINT_DESIGN)介绍
打印设计(PRINT_DESIGN)界面上方有两栏菜单栏,举例说明(文本框,条码,图形等).(1)第一排最左侧第一个功能,位置移动:控制里面元素微上下左右移动,每次移动一个px.(用于微调,普通调整可 ...
- MySQL 大数据量分页优化
假设有一个千万量级的表,取1到10条数据: ,; ,; 这两条语句查询时间应该在毫秒级完成: ,; 你可能没想到,这条语句执行之间在5s左右: 为什么相差这么大? 可能mysql并没有你想的那么智能, ...
- Jenkins+PowerShell持续集成环境搭建(二)控制台项目
1. 新建一个名字为HelloWorld.Console的Freesyle项目: 2. 配置源码管理: 3. 编译配置: 版本:选择MSBuild4 文件:D:\CI\Config\HelloWorl ...
- linux 安装Brew
点击查看原文 Linuxbrew:Linux下的Homebrew amendgit 关注 2017.02.16 17:20* 字数 455 阅读 4745评论 0喜欢 2 前不久还在跟同事抱怨ubun ...
- python史上最全学习路线图
ps:盘它 python入门教程 关注微信公众号,回复"python入门"获取视频下载地址
- Cetos 7 系统安装备注事项
说明:此篇内容为个人记录备注事项,具体的安装操作请参考其他教程: 系统安装: 公司的服务器型号为戴尔R330 卡片式服务器,安装过程中遇到一些问题,此文章中简单记录下 1.下载一份Cetos 系统镜像 ...
- 【CodeForces706E】Working routine(二维链表)
BUPT2017 wintertraining(15) #6B 题意 q次操作,每次把两个给定子矩阵交换,求最后的矩阵.(2 ≤ n, m ≤ 1000, 1 ≤ q ≤ 10 000) 题解 用R[ ...