题目:http://poj.org/problem?id=2449
A*算法详解:https://blog.csdn.net/z_mendez/article/details/47057461
f(n)=g(n)+h(n)
其中f(n)是每个可能试探点的估值,它有两部分组成:一部分为g(n),它表示从起始搜索点到当前点的代价(通常用某结点在搜索树中的深度来表示)。另一部分,即h(n),它表示启发式搜索中最为重要的一部分,即当前结点到目标结点的估值,h(n)设计的好坏,直接影响着具有此种启发式函数的启发式算法的是否能称为A*算法。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#define len 100005
#define inf 0xffffff
using namespace std;
struct node
{
int j,v,next;
}s[len],res[len];
struct ans
{
int f,g,h;
bool operator<(const ans &b)
const{
if(b.f==f) return b.g<g;
else return b.f<f;
}
};
int d[1010],head1[1010],head2[1010];
int k1,k2,S,T,K,sum,m,n;
bool vis[1010];
void add(int x,int y,int z)
{
s[k1].j=y;
s[k1].v=z;
s[k1].next=head1[x];
head1[x]=k1++;
res[k2].j=x;
res[k2].v=z;
res[k2].next=head2[y];
head2[y]=k2++;
}
void spfa(int x)
{
d[x]=0;
vis[x]=1;
queue<int> q;
q.push(x);
while(!q.empty())
{
int t=q.front();
q.pop();
vis[t]=0;
for(int i=head2[t];i!=-1;i=res[i].next)
{
int j=res[i].j;
int v=res[i].v;
if(d[j]>d[t]+v)
{
d[j]=d[t]+v;
if(!vis[j]) q.push(j),vis[j]=1;
}
}
}
}
int A_star(int x,int y)
{
ans t;
if(x==y) K++;
if(d[x]==inf) return -1;
t.h=x;
t.g=0;
t.f=t.g+d[x];
priority_queue<ans> Q;
Q.push(t);
while(!Q.empty())
{
ans temp=Q.top();
Q.pop();
if(temp.h==y) sum++;
if(sum==K) return temp.g;
for(int i=head1[temp.h];i!=-1;i=s[i].next)
{
ans t;
t.h=s[i].j;
t.g=temp.g+s[i].v;
t.f=t.g+d[t.h];
Q.push(t);
}
}
return -1;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
int x,y,z;
sum=0;
k1=k2=1;
for(int i=1;i<=n;i++)
{
head1[i]=head2[i]=-1;
vis[i]=0;
d[i]=inf;
}
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
scanf("%d%d%d",&S,&T,&K);
spfa(T);
printf("%d\n",A_star(S,T));
}
return 0;
}