zoukankan      html  css  js  c++  java
  • UVA10740 Not the Best (K短路)

    题意:求A到B的K短路!

    分析:使用A*算法

     所谓K短路,就是从s到t的第K短的路,第1短就是最短路。

        如何求第K短呢?有一种简单的方法是广度优先搜索,记录t出队列的次数,当t第k次出队列时,就是第k短路了。但点数过大时,入队列的节点过多,时间和空间复杂度都较高。

        A*是在搜索中常用的优化,一种启发式搜索。简单的说,它可以用公式表示为f(n) = g(n) + h(n),其中,f(n)是从s经由节点n到t的估价函数,g(n)是在状态空间中从s到n的实际代价,h(n)是从n到t的最佳路径估计代价。在设计中,要保证h(n)<= n到t的实际代价,这一点很重要,h(n)越接近真实值,速度越快。

     由于启发函数的作用,使得计算机在进行状态转移时尽量避开不可能产生最优解的分支,而选择相对较接近最优解的路径进行搜索,降低了时间和空间复杂度。

      算法过程:

        1. 将图反向,用dijstra+heap求出t到所有点的最短距离,目的是求所有点到点t的最短路,用dis[i]表示i到t的最短路,其实这就是A*的启发函数,显然:h(n)<= n到t的实际代价。

        2. 定义估价函数。我们定义g(n)为从s到n所花费的代价,h(n)为dis[n],显然这符合A*算法的要求。

        3. 初始化状态。状态中存放当前到达的点i,fi,gi。显然,fi=gi+dis[i]。初始状态为(S,dis[S],0),存入优先级队列中。

        4. 状态转移。假设当前状态所在的点v相邻的点u,我们可以得到转换:(V,fv,gv)-->(U,fu+w[v][u],gv+w[v][u])。

        5. 终止条件。每个节点最多入队列K次,当t出队列K次时,即找到解。

    // File Name: 10740.cpp
    // Author: Zlbing
    // Created Time: 2013/5/19 0:44:07
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    #define REP(i,r,n) for(int i=r;i<=n;i++)
    #define RREP(i,n,r) for(int i=n;i>=r;i--)
    const int MAXN=105;
    
    struct Edge{
        int u,v,cost;
    };
    vector<Edge> edges;
    vector<int> G[MAXN];
    vector<Edge> O_edges;
    vector<int> O_G[MAXN];
    int S,T,K;
    struct node{
        int u;
        int f,g;
        bool operator <(const node& rhs)const{
            return f>rhs.f;
        }
    };
    int h[MAXN];
    void dij(int t)
    {
        priority_queue<node> Q;
        CL(h,-1);
        Q.push((node){t,0,0});
        while(!Q.empty())
        {
            node tmp=Q.top();
            Q.pop();
            int u=tmp.u;
            int cost=tmp.f;
            if(h[u]!=-1)continue;
            h[u]=cost;
            for(int i=0;i<O_G[u].size();i++)
            {
                int mm=O_G[u][i];
                Edge e=O_edges[mm];
                tmp.u=e.v;
                tmp.f=e.cost+cost;
                Q.push(tmp);
            }
        }
    }
    int cnt[MAXN];
    int a_star()
    {
        CL(cnt,0);
        priority_queue<node> Q;
        if(h[S]==-1)return -1;
        Q.push((node){S,h[S],0});
        node t,tt;
        while(!Q.empty())
        {
            t=Q.top();
            Q.pop();
            int u=t.u;
            int f=t.f;
            int g=t.g;
            cnt[u]++;
            if(cnt[T]==K)return g;
            if(cnt[u]>K)continue;
            for(int i=0;i<G[u].size();i++)
            {
                Edge e=edges[G[u][i]];
                tt.u=e.v;
                tt.g=g+e.cost;
                tt.f=tt.g+h[tt.u];
                Q.push(tt);
            }
        }
        return -1;
    }
    int main()
    {
        int n,m;
        while(~scanf("%d%d",&n,&m))
        {
            if(n==0&&m==0)break;
            REP(i,0,n){
                G[i].clear();
                O_G[i].clear();
            }
            edges.clear();
            O_edges.clear();
            scanf("%d%d%d",&S,&T,&K);
            int a,b,c;
            REP(i,1,m)
            {
                scanf("%d%d%d",&a,&b,&c);
                edges.push_back((Edge){a,b,c});
                O_edges.push_back((Edge){b,a,c});
                int mm=edges.size();
                G[a].push_back(mm-1);
                O_G[b].push_back(mm-1);
            }
            dij(T);
            int ans=a_star();
            printf("%d\n",ans);
        }
        return 0;
    }
  • 相关阅读:
    .net测试篇之Moq行为配置
    .net测试篇之Moq框架简单使用
    .net测试篇之测试神器Autofixture在几个复杂场景下的使用示例以及与Moq结合
    .net测试篇之测试神器Autofixture Generator使用与自定义builder
    .net测试篇之测试神器Autofixture基本配置一
    .net测试篇之单元测试/集成测试神器Autofixture
    .netcore持续集成测试篇之web项目验收测试
    .netcore持续集成测试篇之 .net core 2.1项目集成测试
    .netcore持续集成测试篇之MVC层单元测试
    .netcore持续集成测试篇之测试方法改造
  • 原文地址:https://www.cnblogs.com/arbitrary/p/3086446.html
Copyright © 2011-2022 走看看