zoukankan      html  css  js  c++  java
  • POJ 2449 Dijstra + A* K短路

    这题一开始的思路应该是直接从源点进行BFS搜索K短路。

    但这样的复杂度在点数和K的值增大后将会变得很大。

    而A*算法则构造一个h(x),在进行BFS时,每次都抛出最小的h(x)从而使汇点的出队速度加快。

    这题则是先进行一次Dijstra求出每个点到汇点的最短路h(x)从而在优先队列中抛出最小的f(x)

    A*算法就是启发式搜索,基本形式就是这样:f(x)=g(x)+h(x);其中f(x)代表在x点所需要的总代价,而g(x)代表:从源点到x点已经耗费的实际代价,h(x)代表从x到终点需要的估计代价,这个函数是一个估计值.而从x到终点真正需要的代价为h*(x),在整个启发式搜索中我们必须保证h(x)<=h*(x);不然的话会由于对当前的估价值过高,则会引起答案的错误。构建A*的关键在于准确的规划一个h(x)函数,使得接近h*(x),这样的搜索会使得答案又快又准。可以想象h(x)过小会使得解空间过大,这样搜索出来的结果会很准确但是速度太慢,而对h(x)的过高估计,即估计代价太大会使得结果不准确。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #define MAXN 1005
    #define MAXM 200100
    using namespace std;
    
    struct Node{
           int v,c,nxt;
    }Edge[MAXM];
    
    int head[MAXN];
    int tail[MAXN];
    int h[MAXN];
    
    struct Statement
    {
           int v,d,h;
           bool operator <( Statement a )const
           {    return a.d+a.h<d+h;   }
    };
    
    void addEdge( int u,int v,int c,int e )
    {
         Edge[e<<1].v=v;
         Edge[e<<1].c=c;
         Edge[e<<1].nxt=head[u];
         head[u]=e<<1;
         
         Edge[e<<1|1].v=u;
         Edge[e<<1|1].c=c;
         Edge[e<<1|1].nxt=tail[v];
         tail[v]=e<<1|1;
         return ;
    }
    
    void Dijstra( int n,int s,int t )
    {
         bool vis[MAXN];
         memset( vis,0,sizeof(vis) );
         memset( h,0x7F,sizeof(h) );
         h[t]=0;
         for( int i=1;i<=n;i++ )
         {
              int min=0x7FFF;
              int k=-1;
              for( int j=1;j<=n;j++ )
              {
                   if( vis[j]==false && min>h[j] )
                       min=h[j],k=j;
              }
              if( k==-1 )break;
              vis[k]=true;
              for( int temp=tail[k];temp!=-1;temp=Edge[temp].nxt )
              {
                   int v=Edge[temp].v;
                   if( h[v]>h[k]+Edge[temp].c )
                       h[v]=h[k]+Edge[temp].c;
              }
         }
    }
    
    int Astar_Kth( int n,int s,int t,int K )
    {
        Statement cur,nxt;
        //priority_queue<Q>q;
        priority_queue<Statement>FstQ;
        
        int cnt[MAXN];
        memset( cnt,0,sizeof(cnt) );
        cur.v=s;
        cur.d=0;
        cur.h=h[s];
        
        FstQ.push(cur);
        
        while( !FstQ.empty() )
        {
               cur=FstQ.top();
               FstQ.pop();
               
               cnt[cur.v]++;
               if( cnt[cur.v]>K ) continue;
               if( cnt[t]==K )return cur.d;
               
               for( int temp=head[cur.v];temp!=-1;temp=Edge[temp].nxt )
               {
                    int v=Edge[temp].v;
                    nxt.d=cur.d+Edge[temp].c;
                    nxt.v=v;
                    nxt.h=h[v];
                    FstQ.push(nxt);
               }
        }
        return -1;
    }
    
    int main()
    {
        int n,m;
        while( scanf( "%d %d",&n,&m )!=EOF )
        {
               int u,v,c;
               memset( head,0xFF,sizeof(head) );
               memset( tail,0xFF,sizeof(tail) );
               
               for( int i=0;i<m;i++ )
               {
                    scanf( "%d %d %d",&u,&v,&c );
                    addEdge( u,v,c,i );
               }
               int s,t,k;
               scanf( "%d %d %d",&s,&t,&k );
               if( s==t ) k++;
               Dijstra( n,s,t );
               printf( "%d
    ",Astar_Kth( n,s,t,k ) );
        }
        return 0;
    }


     

  • 相关阅读:
    BZOJ3752 : Hack
    XIV Open Cup named after E.V. Pankratiev. GP of SPb
    XIII Open Cup named after E.V. Pankratiev. GP of Ukraine
    BZOJ2087 : [Poi2010]Sheep
    BZOJ2080 : [Poi2010]Railway
    BZOJ2082 : [Poi2010]Divine divisor
    Moscow Pre-Finals Workshop 2016. National Taiwan U Selection
    XIII Open Cup named after E.V. Pankratiev. GP of Asia and South Caucasus
    XIII Open Cup named after E.V. Pankratiev. GP of Azov Sea
    XIII Open Cup named after E.V. Pankratiev. GP of SPb
  • 原文地址:https://www.cnblogs.com/amourjun/p/5134136.html
Copyright © 2011-2022 走看看