zoukankan      html  css  js  c++  java
  • poj 2449 k短路+A*算法

    http://poj.org/problem?id=2449

    K短路的定义:
    1.如果起点终点相同,那么0并不是最短路,而是要出去一圈回来之后才是最短路,那么第K短路也是一样。
    2.每个顶点和每条边都可以使用多次。(可以存在环和来回走)

    给定起终点,求K短路的长度


    然后求K短路使用A*算法,其估价函数f(n) = g(n)+h(n),h(n)是终点到结点n的最短路径,g(n)是起点到结点n的实际代价, 这样选择显然能满足A*估价函数的要求,g(n)>=g'(n),
    h(n)<=h'(n)。
    h(n)可以对原图的逆图进行SPFA得出。
    终止条件是,如果终点第K次出队的话,那么表明已经找到第K短路。
    注意处理起点终点不连通的情况。

    #pragma comment(linker, "/STACK:36777216")
    #pragma GCC optimize ("O2")
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <map>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define RD(x) scanf("%d",&x)
    #define RD2(x,y) scanf("%d%d",&x,&y)
    #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define clr0(x) memset(x,0,sizeof(x))
    #define clr1(x) memset(x,-1,sizeof(x))
    #define eps 1e-9
    const double pi = acos(-1.0);
    typedef long long LL;
    typedef unsigned long long ULL;
    const int modo = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    const int inf = 0x3fffffff;
    const int maxn = 1005,maxm = 100005;
    struct edge{
        int v,w,next;
        edge(){};
        edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};
    }e[maxm<<1];
    struct node{
        int f,g,v;
        node(){};
        node(int ff,int gg,int vv):f(ff),g(gg),v(vv){};
        bool operator < (const node &a) const{
            return a.f < f;
        }
    };
    int head[maxn],tail[maxn],dist[maxn],inq[maxn];
    int n,m,s,t,k,ecnt;
    void init()
    {
        clr1(head),clr1(tail);
        ecnt = 0;
        fill(dist,dist+maxn,inf);
        clr0(inq);
    }
    void add(int u,int v,int w)
    {
        e[ecnt] = edge(v,w,head[u]);
        head[u] = ecnt++;
        e[ecnt] = edge(u,w,tail[v]);
        tail[v] = ecnt++;
    }
    void spfa(int src)
    {
        queue<int> q;
        q.push(src);dist[src] = 0,inq[src] = 1;
        while(!q.empty()){
            int cur = q.front();
            q.pop();inq[cur] = 0;
            for(int i = tail[cur];i != -1;i = e[i].next){
                int nxt = e[i].v;
                if(dist[nxt] > dist[cur] + e[i].w){
                    dist[nxt] = dist[cur] + e[i].w;
                    if(!inq[nxt])
                        inq[nxt] = 1,q.push(nxt);
                }
            }
        }
    
    }
    int Astar(int src,int dst){
        priority_queue<node> q;
        if(dist[src] == inf)
            return -1;
        clr0(inq);
        q.push(node(dist[src],0,src));
        while(!q.empty()){
            node cur = q.top();
            q.pop();
            inq[cur.v]++;
            if(inq[dst] == k)
                return cur.f;
            if(inq[cur.v] > k)
                continue;
            for(int i = head[cur.v];i != -1;i = e[i].next){
                node nxt(dist[e[i].v] + e[i].w + cur.g,e[i].w + cur.g,e[i].v);
                q.push(nxt);
            }
        }
        return -1;
    }
    int main(){
        int u,v,w;
        while(~RD2(n,m)){
            init();
            while(m--){
                RD3(u,v,w);u--,v--;
                add(u,v,w);
            }
            RD3(s,t,k);s--,t--;
            spfa(t);
            if(s == t)//如果起点终点相同,0不是第1短路径。。
                k++;
            printf("%d
    ",Astar(s,t));
        }
        return 0;
    }
    


  • 相关阅读:
    sass中使用穿透属性(deep)修改第三方组件样似
    Codeforces Round #647 (Div. 2) D. Johnny and Contribution(BFS)
    Codeforces Round #647 (Div. 2) C. Johnny and Another Rating Drop(数学)
    Codeforces Round #647 (Div. 2) B. Johnny and His Hobbies(枚举)
    Codeforces Round #647 (Div. 2) A. Johnny and Ancient Computer
    AtCoder Beginner Contest 169
    Codeforces Round #646 (Div. 2) E. Tree Shuffling(树上dp)
    Codeforces Round #646 (Div. 2) C. Game On Leaves(树上博弈)
    Codeforces Round #646 (Div. 2) B. Subsequence Hate(前缀和)
    Codeforces Round #646 (Div. 2) A. Odd Selection(数学)
  • 原文地址:https://www.cnblogs.com/zibaohun/p/4074380.html
Copyright © 2011-2022 走看看