k短路.
A*求k短路就是用估价函数优化暴力搜索,选择估价最短的状态优先扩展,然后发现一个性质:第k短的路径第k个被搜到(出队),这个MS挺显然…
然后k短路就讲完了…
这题原题空限是256M,BZOJ上64M,于是怒被卡,被出题人坑了一波…
AC code:
#include <cstdio>
#include <queue>
using namespace std;
typedef long double llf;
const int N=200010;
const int INF=1<<29;
int n,m,S,T,tot,K,ans;
int h1[N],h2[N],cnt[N];
llf dist[N];
llf e;
struct edge{
int u,v,next;
llf w;
edge() {}
edge(int u,int v,llf w,int next):u(u),v(v),w(w),next(next) {}
}E1[N],E2[N];
struct data{
int u;
llf g;
data() {}
data(int u,llf g):u(u),g(g) {}
friend bool operator<(data x,data y){
return x.g+dist[x.u]>y.g+dist[y.u];
}
};
void addedge(int u,int v,llf w){
E1[++tot]=edge(u,v,w,h1[u]);
h1[u]=tot;
E2[tot]=edge(v,u,w,h2[v]);
h2[v]=tot;
}
void SPFA(){
queue<int> Q;
for(int i=1;i<=n;i++) dist[i]=INF;
dist[T]=0;
Q.push(T);
while(!Q.empty()){
int x=Q.front();
Q.pop();
for(int i=h2[x];i;i=E2[i].next){
if(dist[x]+E2[i].w>=dist[E2[i].v]) continue;
dist[E2[i].v]=dist[x]+E2[i].w;
Q.push(E2[i].v);
}
}
}
void work(){
priority_queue<data> Q;
Q.push(data(S,0));
while(!Q.empty()){
data x=Q.top();
Q.pop();
cnt[x.u]++;
K=cnt[T]+(int)(e/(x.g+dist[x.u]));
if(x.u==T){
if(x.g>e) break;
else{
ans++;
e-=x.g;
continue;
}
}
for(int i=h1[x.u];i;i=E1[i].next)
if(x.g+dist[x.u]<=e&&cnt[E1[i].v]<=K) Q.push(data(E1[i].v,x.g+E1[i].w));
}
printf("%d\n",ans);
}
int main(){
freopen("BZOJ1975.in","r",stdin);
freopen("BZOJ1975.out","w",stdout);
scanf("%d%d%lf",&n,&m,&e);
S=1;T=n;
for(int i=1;i<=m;i++){
int u,v;
llf w;
scanf("%d%d%lf",&u,&v,&w);
addedge(u,v,w);
}
SPFA();
work();
fclose(stdin);
fclose(stdout);
return 0;
}