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*)的更多相关文章

  1. POJ 2449 Remmarguts' Date --K短路

    题意就是要求第K短的路的长度(S->T). 对于K短路,朴素想法是bfs,使用优先队列从源点s进行bfs,当第K次遍历到T的时候,就是K短路的长度. 但是这种方法效率太低,会扩展出很多状态,所以 ...

  2. POJ 2449Remmarguts' Date K短路模板 SPFA+A*

    K短路模板,A*+SPFA求K短路.A*中h的求法为在反图中做SPFA,求出到T点的最短路,极为估价函数h(这里不再是估价,而是准确值),然后跑A*,从S点开始(此时为最短路),然后把与S点能达到的点 ...

  3. BZOJ-1975 魔法猪学院 K短路 (A*+SPFA)

    1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1323 Solved: 433 [Submit][Statu ...

  4. 【POJ】2449 Remmarguts' Date(k短路)

    http://poj.org/problem?id=2449 不会.. 百度学习.. 恩. k短路不难理解的. 结合了a_star的思想.每动一次进行一次估价,然后找最小的(此时的最短路)然后累计到k ...

  5. poj 2449 Remmarguts' Date K短路+A*

    题目链接:http://poj.org/problem?id=2449 "Good man never makes girls wait or breaks an appointment!& ...

  6. 第k短路

    poj 2449 模板题  A*+spfa #include<iostream> #include<cstdio> #include<cstring> #inclu ...

  7. poj 2449(A*求第K短路)

    题目链接:http://poj.org/problem?id=2449 思路:我们可以定义g[x]为源点到当前点的距离,h[x]为当前点到目标节点的最短距离,显然有h[x]<=h*[x](h*[ ...

  8. K短路

    K短路 用dijsktra+A*启发式搜索当点v第K次出堆的时候,这时候求得的路径是k短路.A*算法有一个启发式函数f(p)=g(p)+h(p), 即评估函数=当前值+当前位置到终点的最短距离g(p) ...

  9. poj 2449 Remmarguts' Date(第K短路问题 Dijkstra+A*)

    http://poj.org/problem?id=2449 Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Subm ...

  10. bzoj 1975 [Sdoi2010]魔法猪学院(k短路)

    题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的:元素与 ...

随机推荐

  1. python之路--前端CSS

    一.CSS介绍 CSS(Cascading Style Sheet,层叠样式表)定义了如何显示HTML元素,给HTML设置样式,让他更加美观. 当浏览器读到这个样式表, 他就会按照这个样式来对文档进行 ...

  2. Python 常用模块总结

    模块的分类: 1.内置模块(python自带的比如像os,sys等模块)    2.自定义模块,自己写的一些模块    3.第三方模块(开源模块) 模块导入: 1.import sys         ...

  3. Java HashMap的put操作(Java1.6)

    https://www.cnblogs.com/skywang12345/p/3310835.html // 存储数据的Entry数组,长度是2的幂. // HashMap是采用拉链法实现的,每一个E ...

  4. qtp自动化测试-条件语句 if select case

    1 if 语句 if  condition  then end if If condition Then   [statements] [ElseIf condition-n Then   [else ...

  5. (转载)C#使用MemoryStream类读写内存

    MemoryStream和BufferedStream都派生自基类Stream,因此它们有很多共同的属性和方法,但是每一个类都有自己独特的用法.这两个类都是实现对内存进行数据读写的功能,而不是对持久性 ...

  6. Apache ab 单测 分布式

    使用synchronized 处理并发 缺点:无法做到细粒度控制 只适合单点的情况 使用Redis作为分布式锁 setnx命令 设计模式 :使用 !setnx 加锁 getset命令

  7. Mybatis -SqlMapConfig.xml环境配置

    SqlMapConfig.xml的配置内容和顺序如下(顺序不能乱): Properties(属性) Settings(全局参数设置) typeAliases(类型别名) typeHandlers(类型 ...

  8. DotNetty 实现 Modbus TCP 系列 (一) 报文类

    本文已收录至:开源 DotNetty 实现的 Modbus TCP/IP 协议 Modbus TCP/IP 报文 报文最大长度为 260 byte (ADU = 7 byte MBAP Header ...

  9. PlaNet,使用图像输入来学习世界模型

    Google AI团队与DeepMind合作,上周宣布了一个名为PlaNet的新的开源“Deep Planning”网络. PlaNet是一个人工智能代理,它只使用图像输入来学习世界模型,并使用这些模 ...

  10. 数据库中事务的四大特性(ACID)

    本篇讲诉数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别. 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity) 原子性是指事务 ...