BZOJ 1975 魔法猪学院(A*求K短路)

显然每次贪心的走最少消耗的路径即可。那么也就是找出最短路,次短路,,,K短路之后消耗E的能量的最多的路径条数。

也就是裸的A*算法。

 

#include <bits/stdc++.h>
using namespace std;
typedef double lf;
const int N=5005, M=200005;
lf d[N], En;
typedef pair<lf, int> pr;
#define mkpr(x, y) make_pair<lf, int> (x, y)
priority_queue<pr, vector<pr>, greater<pr> >q;
struct Gr {
    struct E {
        int next, to;
        lf w;
    }e[M];
    int n, ihead[N], cnt;
    void add(int x, int y, lf w) {
        e[++cnt]=(E){ihead[x], y, w}; ihead[x]=cnt;
    }
    void dij() {
        static bool vis[N];
        memset(vis, 0, sizeof(bool)*(n+1));
        for(int i=1; i<=n; ++i) {
            d[i]=1e150;
        }
        d[n]=0;
        q.push(mkpr((lf)0, n));
        while(q.size()) {
            int x=q.top().second;
            q.pop();
            if(vis[x]) {
                continue;
            }
            vis[x]=1;
            for(int i=ihead[x]; i; i=e[i].next) {
                int y=e[i].to;
                if(d[y]>d[x]+e[i].w) {
                    d[y]=d[x]+e[i].w;
                    q.push(mkpr(d[y], y));
                }
            }
        }
    }
    int getans() {
        int ans=0;
        q.push(mkpr(d[1], 1));
        while(En>0 && q.size()) {
            int x=q.top().second;
            lf g=q.top().first-d[x];
            q.pop();
            if(x==n) {
                if(En>=g) {
                    En-=g;
                    ++ans;
                    continue;
                }
                else {
                    break;
                }
            }
            for(int i=ihead[x]; i; i=e[i].next) {
                int y=e[i].to;
                lf w=e[i].w;
                // 有精度误差啊,不能乱减枝啊
                q.push(mkpr(g+w+d[y], y));
            }
        }
        return ans;
    }
}g, G;
int main() {
    int n, m;
    scanf("%d%d%lf", &n, &m, &En);
    g.n=G.n=n;
    for(int i=1; i<=m; ++i) {
        int x, y;
        lf e;
        scanf("%d%d%lf", &x, &y, &e);
        g.add(x, y, e);
        G.add(y, x, e);
    }
    G.dij();
    printf("%d\n", g.getans());
    return 0;
}
View Code

 

posted @ 2017-05-16 14:03  free-loop  阅读(155)  评论(0编辑  收藏  举报