A*算法求K短路(POJ 2449 Remmarguts' Date)

A*算法求K短路(POJ 2449 Remmarguts' Date)
静态链表实现图存储
#include  < stdio.h >
#include  < string .h >
#include  < queue >
#include  < stack >
#include  < vector >
using  namespace  std;

const  int  INF  =  1e8;

const  int  NUMV  =  1200 ; // number of vertex
const  int  NUME  =  120010 ; // number of edge

int  head[NUMV];
int  ux[NUME], vx[NUME]; // edge: ux->vx
int  next[NUME], cost[NUME];

int  instk[NUMV]; // in stack or not
int  dist[NUMV];  // shortest distance from dest to each vertex
int  cnt[NUMV];  // count the times of a node out of queue

int  n, m;
int  s, t, k;

struct  Node {
     int  f, g; // f = g + h
     int  v;
    Node( int  a,  int  b,  int  c):f(a),g(b),v(c){}
     bool  operator  <  ( const  Node &  a) const  {
         return  a.f  <  f;
    }
};

int  spfa( int  s,  int  t,  int  vx[]) {
    stack < int >  stk;
     // initial instk[] and dist[]
     for  ( int  i  =  0 ; i  <=  n;  ++ i) {
        instk[i]  =  0 ;
        dist[i]  =  INF;
    }
     // push s into the stack
    dist[s]  =  0 ;
    instk[s]  =  1 ;
    stk.push(s);
     while  ( ! stk.empty()) {
         int  cur  =  stk.top();
        stk.pop();
        instk[cur]  =  0 ;
         for  ( int  i  =  head[cur]; i  >=  0 ; i  =  next[i]) {
             if  (dist[cur] + cost[i]  <  dist[vx[i]]) {
                dist[vx[i]]  =  dist[cur] + cost[i];
                 if  ( ! instk[vx[i]]) {
                    stk.push(vx[i]);
                    instk[vx[i]]  =  1 ;
                }
            }
        }
    }
     if  (dist[t]  ==  INF)  return  0 ;
     else  return  1 ;
}
/*
int q[NUMV];
void Spfa(int s,int t, int vx[])
{
    int i,u,v,l,r=0,tmp;
    for(i=0;i<=n;++i)dist[i]=INF,instk[i]=0;
    dist[s]=0;
    q[r++]=s;
    for(l=0;l<r;++l)
        for(i=head[u=q[l]],instk[u]=0;i>=0;i=next[i])
            if((tmp=dist[u]+cost[i])<dist[v=vx[i]])
            {
                dist[v]=tmp;
                if(instk[v])continue;
                instk[q[r++]=v]=1;
            }
}
*/
int  A_star( int  s,  int  t,  int  vx[]) {
     if  (dist[s]  >=  INF)  return  - 1 ;
     for  ( int  i  =  0 ; i  <=  n;  ++ i) cnt[i]  =  0 ;
    priority_queue < Node >  nodeq;
    nodeq.push(Node(dist[s], 0 ,s));
     while  ( ! nodeq.empty()) {
        Node cur  =  nodeq.top();
        nodeq.pop();
         ++ cnt[cur.v];
         if  (cnt[cur.v]  >  k)  continue ;
         if  (cnt[t]  ==  k)  return  cur.f;
         for  ( int  i  =  head[cur.v]; i  >=  0 ; i  =  next[i]) {
             int  g  =  cur.g  +  cost[i];
             int  f  =  g  +  dist[vx[i]];
             int  v  =  vx[i];
            nodeq.push(Node(f,g,v));
        }
    }
     return  - 1 ;
}

int  main( void )
{
     while  (scanf( " %d %d " & n,  & m)  ==  2 ) {
        memset(head,  - 1 sizeof (head));
         for  ( int  i  =  0 ; i  <  m;  ++ i) {
            scanf( " %d %d %d " , ux + i, vx + i, cost + i);
            next[i]  =  head[vx[i]];
            head[vx[i]]  =  i;
        }
        scanf( " %d %d %d " & s,  & t,  & k);
         if  (s  ==  t) k  +=  1 ;
        spfa(t, s, ux);

        memset(head,  - 1 sizeof (head));
         for  ( int  i  =  0 ; i  <  m;  ++ i) {
            next[i]  =  head[ux[i]];
            head[ux[i]]  =  i;
        }
        printf( " %d\n " , A_star(s, t, vx));
    }
     return  0 ;
}

容器实现图存储
#include <stdio.h>
#include < string .h>
#include <queue>
#include <stack>
#include <vector>
using  namespace  std;

const  int  INF = 1e8;
const  int  NUMV = 1010;
const  int  NUME = 100010;

struct  Node {
     int  f, g;
     int  v;
    Node ( int  a,  int  b,  int  c):f(a),g(b),v(c) {}
     bool  operator  < ( const  Node& a)  const  {
         return  a.f < f;
    }
};

struct  Edge {
     int  u, v; // from u to v
     int  w; // cost 
};

vector<Edge> edges;
vector< int > G[NUMV];
vector< int > iG[NUMV]; // inverse graph

int  dist[NUMV]; // shotest distance
int  instk[NUMV]; // in stack :spfa
int  n, m;
int  s, t, k;

void  add_edge(vector< int > G[],  int  u,  int  v,  int  w) {
    edges.push_back((Edge){u,v,w});
     int  m = edges.size();
    G[u].push_back(m-1);
}

void  spfa( int  s,  int  t, vector< int > G[])
{
    stack< int > stk;
     for  ( int  i = 0; i < n; ++i) {
        dist[i] = INF;
        instk[i] = 0;
    }
    dist[s] = 0;
    stk.push(s);
    instk[s] = 1;
     while  (!stk.empty()) {
         int  u = stk.top();
        stk.pop();
        instk[u] = 0;
         for  ( int  i = 0; i < G[u].size(); ++i) {
            Edge& e = edges[G[u][i]];
             if  (dist[u]+e.w < dist[e.v]) {
                dist[e.v] = dist[u]+e.w;
                 if  (!instk[e.v]) {
                    stk.push(e.v);
                    instk[e.v] = 1;
                }
            }
        }
    }
}

int  A_star( int  s,  int  t, vector< int > G[]) {
     if  (dist[s] >= INF)  return  -1;
    priority_queue<Node> nodeq;
    nodeq.push(Node(dist[s], 0, s));
     int  cnt = 0;
     while  (!nodeq.empty()) {
        Node cur = nodeq.top();
        nodeq.pop();
         if  (cur.v == t) ++cnt;
         if  (cnt == k)  return  cur.f;
         for  ( int  i = 0; i < G[cur.v].size(); ++i) {
            Edge &e = edges[G[cur.v][i]];
             int  v = e.v;
             int  g = cur.g + e.w;
             int  f = g + dist[v];
            nodeq.push(Node(f, g, v));
        }
    }
     return  -1;
}

void  clear() {
     for  ( int  i = 0; i < n; ++i) {
        G[i].clear();
        iG[i].clear();
    }
    edges.clear();

}

int  main( void )
{
     while  (scanf("%d %d", &n, &m) == 2) {
         for  ( int  i = 0; i < m; ++i) {
             int  u, v, w;
            scanf("%d %d %d", &u, &v, &w);
            add_edge(G, u, v, w);
            add_edge(iG, v, u, w);
        }
        scanf("%d %d %d", &s, &t, &k);
        spfa(t, s, iG);
         if  (s == t) ++k;
        printf("%d\n", A_star(s, t, G));
        clear();
    }
     return  0;
}

你可能感兴趣的:(A*算法求K短路(POJ 2449 Remmarguts' Date))