• 第k短路


    http://acm.pku.edu.cn/JudgeOnline/problem?id=2449 

    有向图上求两点st, ed间的第k短的路径

    emmm......

    朴素的想法就是priority_queue,从原点出发向外探索,当取出终点k次时就得到第k短路

    类似“bfs”的思想,缺陷是越往后状态数越多

    改进一下,这里有个A*算法,比果体的搜索要好

    在A*里面我们通过优先展开到ed近的状态,使搜索方向靠近答案,而不是一层一层全都展开

    估价函数f=g+h f是估计的st到ed的距离,g是到达当前点已经点的花费,h是预计剩下的花费

    h如果完全为真实值 那搜索就会笔直朝向答案前进没有浪费,如果h不那么准确,emmm问题不大,只是会晚点找到答案

    我们表面上说h差不多就行,然而我们都知道,h的设计很重要

    在这里h可以取当前点的距离到ed距离 通过反向建边,从ed跑一遍dijkstra可以预处理出距离数组

    反向建边值得好好体会,边就在那里,只是head和next的连接一正一反

    还有个细节就是st==ed时给k++,不然还没移动呢就有一次取出的计数了

    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    // f = g + h;
    const int maxn = 1e3+7, maxm = 1e5+7, INF = 0x3f3f3f3f;
    int head[maxn], rhead[maxn], vis[maxn], d[maxn], cur;
    struct edge{
        int rv, v, w, nxt, rnxt;
        edge(){}
        edge(int rv, int v, int w, int nxt, int rnxt):rv(rv), v(v), w(w), nxt(nxt), rnxt(rnxt){}
    }e[maxm];
    typedef pair<int, int>pi;
    struct state{
        int g, h, v;// g cost h pending
        state(){}
        state(int g, int h, int v):g(g), h(h), v(v){}
        bool operator < (const state tmp)const{
            return g + h > tmp.g + tmp.h;
        }
    };// greater<state> not defined
    void addedge(int u, int v, int w){
        e[cur] = edge(u, v, w, head[u], rhead[v]);
        head[u] = cur;
        rhead[v] = cur++;
    }
    void dijkstra(int st){// distance from "st"
        memset(d, INF, sizeof(d));
        memset(vis, 0, sizeof(vis));
        priority_queue<pi, vector<pi>, greater<pi> >P;
        d[st] = 0;
        P.push(make_pair(0, st));
        while(!P.empty()){
            pi x = P.top();
            P.pop();
            int u = x.second, dis = x.first;
            if(vis[u])
                continue;
            vis[u] = 1;
            for(int i = rhead[u]; ~i; i = e[i].rnxt){
                int rv = e[i].rv, w = e[i].w, len = dis+w;
                if(d[rv] > len){
                    d[rv] = len;
                    P.push(make_pair(d[rv], rv));
                }
            }
        }
    }
    int Astar(int st, int ed, int k){
        if(st == ed)
            k++;
        if(d[st] == INF)
            return -1;
        priority_queue<state>P;
        P.push(state(0, d[st], st));
        while(!P.empty()){
            state x = P.top();
            P.pop();
            int g = x.g, u = x.v;
            if(u == ed){
                if(k > 1)
                    k--;
                else
                    return g;
            }
            for(int i = head[u]; ~i; i = e[i].nxt){
                int v = e[i].v, w = e[i].w;
                P.push(state(g+w, d[v], v));
            }
        }
        return -1;
    }
    int main(){
        int n, m;
        while(~scanf("%d%d", &n, &m)){
            cur = 0;
            memset(head, -1, sizeof(head));
            memset(rhead, -1, sizeof(rhead));
            while(m--){
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                addedge(u, v, w);
            }
            int st, ed, k;
            scanf("%d%d%d", &st, &ed, &k);
            dijkstra(ed);
            printf("%d
    ", Astar(st, ed, k));
        }
        return 0;
    }
    搞图论是没有用的,转行做数学题了hh
  • 相关阅读:
    python邮件之附件
    python3.5之smtp
    一台Linux上搭建两个tomcat
    mysql 初探(一)
    python监视mysql最大连接数
    P3658 [USACO17FEB]Why Did the Cow Cross the Road III P cdq分治
    P4793 [AHOI2008]矩形藏宝地 cdq分治 线段树
    P2487 [SDOI2011]拦截导弹 线段树 cdq分治
    P3157 [CQOI2011]动态逆序对 cdq分治
    P4169 [Violet]天使玩偶/SJY摆棋子 cdq分治
  • 原文地址:https://www.cnblogs.com/DearDongchen/p/7492634.html
Copyright © 2020-2023  润新知