• POJ 2449 Remmarguts' Date(第K短路 + A* + 最短路)题解


    题意:找出第k短路,输出长度,没有输出-1

    思路:这题可以用A*做。A*的原理是这样,我们用一个函数:f = g + h 来表示当前点的预期步数,f代表当前点的预期步数,g代表从起点走到当前的步数,h代表从当前点走到终点的最短路,显然h可以用最短路解出。那么我们从起点开始找,每次找f最小的点,直到找到第k个这样的点。

    代码:

    #include<queue>
    #include<cstring>
    #include<set>
    #include<map>
    #include<stack>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    typedef long long ll;
    using namespace std;
    const int maxn = 1000 + 10;
    const int seed = 131;
    const ll MOD = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    int n, m, k, tot;
    struct Edge{
        int v, w, next;
    }edge[maxn * 100];
    struct As{
        int f, g, pos;
        bool operator < (const As a) const{
            return a.f == f? a.g < g : a.f < f;
        }
    };
    struct que{
        int u, v, w;
    }q[100005];
    int head[maxn], dis[maxn];
    bool vis[maxn];
    void init(){
        memset(head, -1, sizeof(head));
        tot = 0;
    }
    void addEdge(int u, int v, int w){
        edge[tot].v = v;
        edge[tot].w = w;
        edge[tot].next = head[u];
        head[u] = tot++;
    }
    void spfa(int st){
        for(int i = 0; i <= n; i++) dis[i] = INF;
        memset(vis, false, sizeof(vis));
        vis[st] = true;
        dis[st] = 0;
        queue<int> q;
        while(!q.empty()) q.pop();
        q.push(st);
        while(!q.empty()){
            int u = q.front();
            q.pop();
            vis[u] = false;
            for(int i = head[u]; i != -1; i = edge[i].next){
                int v = edge[i].v;
                int w = edge[i].w;
                if(dis[v] > dis[u] + w){
                    dis[v] = dis[u] + w;
                    if(!vis[v]){
                        vis[v] = true;
                        q.push(v);
                    }
                }
            }
        }
    }
    int Astar(int st, int end){
       int cnt = 0;
       priority_queue<As> q;
       while(!q.empty()) q.pop();
       if(st == end) k++;
       if(dis[st] == INF) return -1;
       As a, b;
       a.pos = st, a.g = 0, a.f = a.g + dis[st];
       q.push(a);
       while(!q.empty()){
            a = q.top();
            q.pop();
            if(a.pos == end){
                cnt++;
                if(cnt == k) return a.f;
            }
            for(int i = head[a.pos]; i != -1; i = edge[i].next){
                b.pos = edge[i].v;
                b.g = a.g + edge[i].w;
                b.f = b.g + dis[b.pos];
                q.push(b);
            }
       }
       return -1;
    }
    int main(){
        while(~scanf("%d%d" ,&n, &m)){
            init();
            for(int i = 1; i <= m; i++){
                scanf("%d%d%d", &q[i].u, &q[i].v, &q[i].w);
                addEdge(q[i].v, q[i].u, q[i].w);
            }
            int s, t;
            scanf("%d%d%d", &s, &t, &k);
            spfa(t);
            init();
            for(int i = 1; i <= m; i++){
                addEdge(q[i].u, q[i].v, q[i].w);
            }
            printf("%d
    ", Astar(s, t));
        }
        return 0;
    }
  • 相关阅读:
    数据查询语句
    数据操作语句
    数据定义语句
    linux的常用命令
    NIO/IO/AIO阻塞/非阻塞/同步/异步
    XCode使用自带SVN,SVN命令
    正则表达式大全——持续更新中。。。
    sql语句优化
    sql一些语句性能及开销优化
    高质量图片无损压缩算法
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9630632.html
Copyright © 2020-2023  润新知