Bzoj1975--Sdoi2010膜法猪学院

显然我们可以对路径长度贪心选取

那么问题就转化成了求1到n的k短路,可以用A*去求。

然后交了两发MLE。QAQ

对于卡空间行为表示强烈谴责

然后卡了卡空间,主要对于一个点超过  魔法值/最短路  次数以上和花费超过当前mana的路径都不必扩展

代码:

#include<bits/stdc++.h>
#define MAXN 5005
#define MAXM 200005
#define INF 1000000000000
#define eps 1e-9
using namespace std;

int n,m,fr[MAXM],to[MAXM],ans;double mana,g[MAXN],cs[MAXM];
bool f[MAXN];

int head[MAXN],cnt;
struct Edge{
    int to,next;double w;
}e[MAXM];
inline void insert(int a,int b,double c) {
    e[++cnt].next=head[a];head[a]=cnt;e[cnt].to=b;e[cnt].w=c;
}

void bfs() {
    for(int i=1;i<=n;i++) g[i]=INF;
    g[n]=0;queue<int> q;q.push(n);f[n]=1;
    while(!q.empty()) {
        int k=q.front();q.pop();
        for(int i=head[k];i;i=e[i].next) {
            if(g[e[i].to]>g[k]+e[i].w) {
                g[e[i].to]=g[k]+e[i].w;
                if(!f[e[i].to]) {f[e[i].to]=1;q.push(e[i].to);}
            }
        }
        f[k]=0;
    }
}

int lim,pt[MAXN];
struct state{
    int p;double h;
    bool operator > (const state &b) const {
        return g[p]+h>g[b.p]+b.h;
    }
};
void Astar() {
    priority_queue<state,vector<state>,greater<state> > q;
    state now,t;now.p=1;now.h=0;q.push(now);lim=ceil(mana/g[1]);
    while(!q.empty()) {
        now=q.top();q.pop();
        if(now.p==n) {
            if(mana-now.h>-eps) {mana-=now.h,ans++;continue;}
            printf("%d\n",ans);exit(0);
        }
        for(int i=head[now.p];i;i=e[i].next) {
            t.h=now.h+e[i].w;t.p=e[i].to;
            if(t.h+g[t.p]<mana&&pt[t.p]<lim) q.push(t),pt[t.p]++;
        }
    }
}

int main() {
    scanf("%d%d%lf",&n,&m,&mana);
    for(int i=1;i<=m;i++) {
        scanf("%d%d%lf",&fr[i],&to[i],&cs[i]);
        insert(to[i],fr[i],cs[i]);
    }
    bfs();
    memset(head,0,sizeof(head));cnt=0;
    for(int i=1;i<=m;i++) insert(fr[i],to[i],cs[i]);
    Astar();
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2016-10-11 09:11  ihopenot  阅读(169)  评论(0编辑  收藏  举报