题目链接:http://poj.org/problem?id=2449
A*搜索求一般的K短路,h()函数其实就是把距离最短,我们开一个优先队列来存放距离最短的点。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 1001;
#define inf (1<<29)
struct nod{
int x,val;
nod() {}
friend bool operator < (const nod& a,const nod& b){
return b.val<a.val;
}
};
vector<struct nod> g[maxn],r[maxn];
priority_queue<nod,vector<nod> > Q;
int n,m,S,T,K,dist[maxn],out[maxn],size;
void dijkstra(){
bool vi[maxn];
vector<struct nod>::iterator iter;
for(int i=1;i<=n;i++){
vi[i]=0;dist[i]=inf;
}
dist[T]=0;
while(1){
int k=-1;
for(int i=1;i<=n;i++)
if(!vi[i] && (k==-1 || dist[i]<dist[k])) k=i;
if(k==-1) break;
vi[k]=1;
vector<struct nod>::iterator iter;
for(iter=r[k].begin();iter!=r[k].end();iter++)
if(!vi[(*iter).x] && dist[(*iter).x]>dist[k]+(*iter).val)
dist[(*iter).x]=dist[k]+(*iter).val;
}
}
int astar(){
dijkstra();
nod v;
v.x=S;v.val=dist[S];
Q.push(v);
vector<struct nod>::iterator iter;
for(int i=0;i<=n;i++) out[i]=0;
while(!Q.empty() && out[T]<K){
v=Q.top();
Q.pop();
if(out[v.x]>=K) continue;
if(v.x==T){
out[v.x]++;
if(v.x==T && out[v.x]==K) return v.val;
}
for(iter=g[v.x].begin();iter!=g[v.x].end();iter++){
if(out[(*iter).x]>=K) continue;
nod tmp;
tmp.val=v.val-dist[v.x]+(*iter).val+dist[(*iter).x];
tmp.x=(*iter).x;
Q.push(tmp);
}
}
return -1;
}
int main(){
while(~scanf("%d%d",&n,&m)){
int a,b,w;
for(int i=1;i<=n;i++) { g[i].clear();r[i].clear(); }
while(m--){
scanf("%d%d%d",&a,&b,&w);
nod tmp;
tmp.x=b;tmp.val=w;
g[a].push_back(tmp);
tmp.x=a;
r[b].push_back(tmp);
}
scanf("%d%d%d",&S,&T,&K);
if(S==T) K++;
int ans=astar();
printf("%d\n",ans);
}
return 0;
}