您的位置:首页 > 其它

[BZOJ1975][Sdoi2010]魔法猪学院

2016-02-20 21:16 295 查看
原题地址

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
,h2
,cnt
;
llf dist
;
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
,E2
;

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: