• [毒瘤][A*][SDOI2010] 魔法猪学院


    先把代码放这, 解释下次再说

    其实让我很不解明明是个 (A^*) 板子为什么还要卡裸 (A^*).. 给我这个只想先打个裸 (A^*) 看看自己理解的对不对 就是懒 的菜鸡带来了极大不便... 然后就直接特判了
    其实一想也算是个提醒吧: 裸 (A^*) 的确很费空间.

    注: 不特判打正解需要可持久化可并堆


    代码:

    # include <iostream>
    # include <cstring>
    # include <cstdio>
    # include <queue>
    # define MAXM 2000005
    # define MAXN 5005
    
    using namespace std;
    
    int n, m;
    double ener;
    
    // Edge Section
    
    struct edge{
        int u, v, next;
        double w;
        bool forw; // forw = 1 为正图上的边
    }e[MAXM<<1];
    int hd[MAXM<<1], cntE;
    
    void AddE(int u, int v, double w){
        e[++cntE].u = u, e[cntE].v = v, e[cntE].w = w, e[cntE].forw = 1, e[cntE].next = hd[u], hd[u] = cntE;
        e[++cntE].u = v, e[cntE].v = u, e[cntE].w = w, e[cntE].forw = 0, e[cntE].next = hd[v], hd[v] = cntE;
    } // 同时新建正反图的边
    
    // Dij Section
    
    struct node{
        int id;
        double val;
        bool operator < (const node that) const{
            return this->val < that.val;
        }
        bool operator > (const node that) const{
            return this->val > that.val;
        }
    };
    
    priority_queue<node, vector<node>, greater<node> >qDij;
    double h[MAXN];
    bool vis[MAXN];
    
    void Dij(int from){
        for(int i = 1; i <= n; i++){
            h[i] = 1e9, vis[i] = 0;
        }
        h[from] = 0;
        qDij.push((node){from, 0});
        while(!qDij.empty()){
            node tmp = qDij.top();
            qDij.pop();
    
            if(vis[tmp.id]){
                continue;
            }
    
            vis[tmp.id] = 1;
    
            for(int i = hd[tmp.id]; i; i = e[i].next){
                if(!e[i].forw){
                    if(h[tmp.id] + e[i].w < h[e[i].v]){
                        h[e[i].v] = h[tmp.id] + e[i].w;
                        qDij.push((node){e[i].v, h[e[i].v]});
                    }
                }
            }
        }
    
    } // 在反图上跑迪杰, 从终点开始
    
    // A* Section
    
    struct star{
        int id;
        double g, f;
        bool operator < (const star that) const{
            return this->g+this->f < that.g+that.f;
        }
        bool operator > (const star that) const{
            return this->g+this->f > that.g+that.f;
        }
    };
    
    priority_queue<star, vector<star>, greater<star> >qAs;
    
    int cnt[MAXN]; // 记录某个点到了几次用于及时跳出
    int ans = 0 ;
    void Astar(int lim){
        if(h[1] > 1e9-5) return;
    
        star tmp, nxt;
        tmp.id = 1, tmp.g=0, tmp.f = 0;
        
        qAs.push(tmp);
        
        while(!qAs.empty()){
            tmp = qAs.top(); qAs.pop();
    
            if(tmp.g > ener) return; // 特判是否到达最大取值
    
            cnt[tmp.id]++;
    
            if(cnt[tmp.id] > lim) continue; // 特判优化
    
            if(tmp.id == n){
                ener -= tmp.g;
                ans++;
                continue;
            } // 每次搜到终点的答案都可以记录, 第 i 次就是第 i 短路
            // 相对于第 i 次搜索来说, 就是最短的
            // 因为更短的方法已经被弹出去了
    
            for(int i = hd[tmp.id]; i; i = e[i].next){
                if(e[i].forw){
                    nxt.id = e[i].v;
                    nxt.f = h[nxt.id];
                    nxt.g = tmp.g + e[i].w;
                    qAs.push(nxt);
                } // 延展到的点压入堆, 关键字为 g+h
            }
        }
    } // g 为实际, h 为预估
    
    // Main Function
    
    int main(){
        scanf("%d%d%lf", &n, &m, &ener);
        
        int ua, va; double wa;
        
        for(int i = 1; i <= m; i++){
            scanf("%d%d%lf", &ua, &va, &wa);
            AddE(ua, va, wa);
        }
    
        Dij(n);
    
        if(ener/h[1]>1000000){
            cout<<2002000;
            return 0;
        } // 特判hack数据
    
        Astar(ener/h[1]); // 最大方案数不能超过 总能量/最短路
    
        printf("%d", ans);
    
        return 0;
    }
    
  • 相关阅读:
    Weblgic安装应用报错:Caused by: com.bea.xml.XmlException: failed to load java type corresponding to e=web-a...
    【Java VisualVM】使用 VisualVM 进行性能分析及调优
    linux如何查看端口被哪个进程占用?
    jvisualVM加载插件及报错 response code:503 for URL和Received fatal alert: protocol_version解决办法
    [BZOJ1381]Knights
    [SHOI2002]舞会
    [POJ1325]Machine Schedule
    [Usaco2005 Jan]Muddy Fields泥泞的牧场
    [Usaco2005 Nov]Asteroids
    [ZOJ1140]Courses 课程
  • 原文地址:https://www.cnblogs.com/Foggy-Forest/p/13345740.html
Copyright © 2020-2023  润新知