luogu2483
这题不知道为什么,我bzoj上死都过不去
然而luogu不断的调数组大小后终于卡过去了(黑人问号
内存206MB。。时间4s+
本题重点就在于求出k短路
然后很简单的贪心减一下就好了
那么接下来问题来了 k短路怎么求
Dijkstra/SPFA+A*
前一个相信大家都知道并且会写
那么注重来讲一下本题中的A*要怎么操作
首先A*的核心在于:f(x)=g(x)+h(x)
那么这里的估价函数h(x)要怎么设计呢
很显然啊。。。x->T的最短路径
所以一开始的dij或者SPFA就是用来求出T到所有节点的估价函数
g(x)为节点走到当前状态的路径长度
注意一下 并不是最短路!
原地绕两下是允许的
接下来我们只要维护一个open表
这题。。连close表都不需要
因为状态本身并不会重复:{x,g(x)}
那么先看一下A*的代码
priority_queue open;
inline void A_star()
{
open.push((hp1){1,1,dis[1]});
g[1]=0;
while(!open.empty())
{
hp1 t=open.top();
open.pop();
if(t.x==n){if(e>=t.val) e-=t.val,ans++;else return;}
for(int i=f[t.x];i;i=nxt[i])
{
int t1=++tot;
int t2=poi[i];
double t3=g[t1]=g[t.num]+v[i];
//cout<' '<' '<open.push((hp1){t1,t2,t3+dis[t2]});
}
}
}
不要问我为什么是大根堆。。
bool operator < (const hp1 &a) const
{
return a.val
然后加上一个dij就可以了
CODE:
#include
#include
#include
#include
#include
#define N 200000
#define For(i,j,k) for(int i=j;i<=k;++i)
using namespace std;
double z,g[500001];
int n,m,x,y,s,cnt,ans,tott;
double c1[N*2],dis[20001],e,v[N*2];
int tot,nxt1[N*2],point1[20001],v1[N*2],poi[N*2],f[20001],nxt[N*2];
bool vis[N*2];
struct hp
{
int x;
double val;
bool operator < (const hp &a) const
{
return a.valstruct hp1
{
int num,x;
double val;
bool operator < (const hp1 &a) const
{
return a.val500001];
priority_queue q;
inline void addedge(int x,int y,double z)
{
nxt1[++tot]=point1[x]; point1[x]=tot; v1[tot]=y; c1[tot]=z;
}
inline void add2(int x,int y,double z)
{
nxt[++cnt]=f[x];f[x]=cnt;poi[cnt]=y;v[cnt]=z;
}
inline void dijkstra()
{
For(i,1,n) dis[i]=10000000.0;
dis[n]=0;
q.push((hp){n,0});
while (!q.empty())
{
int now=q.top().x;
q.pop();
if (vis[now]) continue;
vis[now]=true;
for (int i=point1[now];i;i=nxt1[i])
{
if (!vis[v1[i]]&&dis[now]+c1[i] open;
inline void A_star()
{
open.push((hp1){1,1,dis[1]});
g[1]=0;
while(!open.empty())
{
hp1 t=open.top();
open.pop();
if(t.x==n){if(e>=t.val) e-=t.val,ans++;else return;}
for(int i=f[t.x];i;i=nxt[i])
{
int t1=++tot;
int t2=poi[i];
double t3=g[t1]=g[t.num]+v[i];
open.push((hp1){t1,t2,t3+dis[t2]});
}
}
}
int main()
{
scanf("%d%d%lf",&n,&m,&e);
for (int i=1;i<=m;++i)
{
scanf("%d%d%lf",&x,&y,&z);
addedge(y,x,z);
add2(x,y,z);
}
dijkstra();
A_star();
printf("%d\n",ans);
return 0;
}