对于无向图:
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;
}