1. 程式人生 > >第K短路(A*演算法)

第K短路(A*演算法)

對於無向圖:

SPFA+A*演算法:先用SPFA求目標結點到各個結點的最短路徑;然後,取g(x)為從初始結點到當前結點x的路徑長度,h(x)為從x結點到目標結點的最短路徑長度,即h(x)取dis[x]即可,估價函式f(x)=g(x)+h(x)。

對於有向圖:
SPFA+A*演算法:顯然應將有向邊取反,然後求目標節點到各個結點的最短路徑;後面和上述一樣。

程式碼:

struct node
{
    int u;
    int w;
    node (int uu,int ww):u(uu),w(ww){}
};

void SPFA(int t)
{
    int i;
    for(i=0;i<=n;i++)
    {
        dis[i]=inf;
        vis[i]=0;
    }

    dis[t]=0;
    queue<int>que;
    que.push(t);
    vis[t]=1;
    while(!que.empty())
    {
        int u=que.front();  que.pop();   vis[u]=0;
        for(i=0;i<g[u].size();i++)
        {
            node b=g[u][i];
            int v=b.u;
            if(dis[v]>dis[u]+b.w)
            {
                dis[v]=dis[u]+b.w;
				if(!vis[v])
                {
                    vis[v]=1;
                    que.push(v);
				}
            }
        }
    }
} 

struct cnode
{
    int u;
    int len;
    cnode (int uu,int ww):u(uu),len(ww){}
    friend bool operator < (cnode a,cnode b)//過載比較運算子 
    {
        return a.len+dis[a.u]>b.len+dis[b.u];//g(x)=a.len,h(x)=dis[a.u]
    }
};

int A_star(int s)
{
    int i;
    if(dis[s]==inf)return -1;//若s到t不連通的話,提前終止 
    priority_queue<cnode>que;

    memset(cnt,0,sizeof(cnt));
    que.push(cnode(s,0));
    while(!que.empty())
    {
        cnode a=que.top();que.pop();
        int u=a.u;
        int len=a.len;
        cnt[u]++;
        if(cnt[t]==k)   return len;//k=1,最短路,k=n,第k短路 

        for(i=0;i<g[u].size();i++)
        {
            node b=g[u][i];
            int v=b.u;
            que.push(cnode(v,len+b.w));
        }

    }
    return -1;
}