zoukankan      html  css  js  c++  java
  • 第K短路(A*算法)

    题目链接

    题意:给你一个图以及起点和终点,求起点到终点的第k短路的大小。

    思路:先用迪杰斯特拉求出每个点到终点的最短路,然后用A*算法,令f(x)为每点到终点的距离,将f(x)附加到每条边的边权上,再利用优先队列对最小的进行扩展,直接暴力搜相邻边,则第k个从优先队列中出来的就是正解。思路很明了,代码写起来很复杂。。。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<queue>
    #define ll long long
    using namespace std;
    const int inf = 0x3f3f3f3f;
    const int maxn = 1005;
    struct edge
    {
        int v, w, nxt;
    }G[100005], G2[100005];
    int tot, pre[maxn], t2, p2[maxn];
    struct node 
    {
        int v, d;
        friend bool operator < (node a, node b)     
        {         
            if(a.d!=b.d)
                return a.d>b.d;
            return a.v>b.v; 
        }
    };
    int n, m, k, dist[maxn];
    bool vis[maxn];
    void dijkstra(int s) 
    {
        memset(dist, 0x3f, sizeof(dist));
        memset(vis, 0, sizeof(vis));
        dist[s] = 0;
        priority_queue<node> que;
        node y;
        y.v=s;
        y.d=0;
        que.push(y);
        while (!que.empty())
        {
            node p = que.top();
            que.pop();
            if (vis[p.v])
            {
                continue;
            }
            vis[p.v] = true;
            for (int i = p2[p.v]; ~i; i = G2[i].nxt)
            {
                int v = G2[i].v, w = G2[i].w;
                if (!vis[v] && p.d + w < dist[v])
                {
                    dist[v] = p.d + w;
                    node x;
                    x.v=v;
                    x.d=dist[v];
                    que.push(x);
                }
            }
        }
    }
    struct point 
    {
        int v, h, g;
        friend bool operator < (point a, point b)     
        {         
            return a.h+a.g>b.h+b.g; 
        }
    };
    int times[maxn];
    int Astar(int s, int e) 
    {
        if(dist[s]==inf)
        {
            return -1;
        }
        memset(times, 0, sizeof(times));
        priority_queue<point> Q;
        point y;
        y.v=s;
        y.g=0;
        y.h=0;
        Q.push(y);
        while (!Q.empty()) {
            point p = Q.top();
            Q.pop();
            ++times[p.v];
            if (times[p.v] == k && p.v == e)
            {
                return p.h + p.g;
            }
            if (times[p.v] > k) {
                continue;
            }
            for (int i = pre[p.v]; ~i; i = G[i].nxt)
            {
                point x;
                x.v=G[i].v;
                x.h=p.h+G[i].w;
                x.g=dist[G[i].v];
                Q.push(x);
            }
        }
        return -1;
    }
    int main() {
        int u, v, w, s, e;
        scanf("%d%d", &n, &m);
        tot = t2 = 0;
        memset(pre, -1, sizeof(pre));
        memset(p2, -1, sizeof(p2));
        while(m--)
        {
            scanf("%d%d%d", &u, &v, &w);
            G[tot].v = v;
            G[tot].w = w;
            G[tot].nxt = pre[u];
            pre[u] = tot++;
            G2[t2].v = u;
            G2[t2].w = w;
            G2[t2].nxt = p2[v];
            p2[v] = t2++;
        }
        scanf("%d%d%d", &s, &e, &k);
        if (s == e)
        {
            k++;
        }
        dijkstra(e);
        printf("%d
    ", Astar(s, e));
        return 0;
    }
  • 相关阅读:
    执行chmod -R 777 / 补救
    kill详解
    find详解
    htop详解
    C#正则表达式经典分类整理集合手册
    C# 正则表达式大全
    各种新主流.net混淆加密软件对比
    string format double
    System.Timers.Timer
    System.Threading.Timer
  • 原文地址:https://www.cnblogs.com/2462478392Lee/p/11295840.html
Copyright © 2011-2022 走看看