A*启发式搜索
(poj2449)
int n,k,Start,End;
int dis[maxn]; // 存放每个点到终点的最短距离
bool vis[maxn];
struct heap{
int p,d;
heap(int _p,int _d):p(_p),d(_d){}
bool operator < (const heap &x) const{
return d+dis[p] > x.d+dis[x.p]; // d在反向dij里没有用,在A*函数里为该点到起点的距离(不一定是最短距离!!!)
}
};
/////// ↓构图↓
int head[maxn],rhead[maxn]; // 构反向图是为了求出每个点到终点的最短距离
struct Edge{
int from,to,cost;
int next,rnext;
}e[100005];
int edgenum=0;
void addEdge(int from,int to,int cost){
e[edgenum].from=from;
e[edgenum].to=to;
e[edgenum].cost=cost;
e[edgenum].next=head[from];
head[from]=edgenum;
e[edgenum].rnext=rhead[to];
rhead[to]=edgenum;
edgenum++;
}
///////
void dij(int s){
priority_queue<heap> q;
memset(dis,INF,sizeof(dis));
dis[s]=0;
q.push(heap(s,0));
while(!q.empty()){
int p=q.top().p;
q.pop();
if(vis[p])continue;
vis[p]=true;
for(int i=rhead[p];i!=-1;i=e[i].rnext){
int v=e[i].from;
if(dis[p]+e[i].cost<dis[v]){
dis[v]=dis[p]+e[i].cost;
q.push(heap(v,0));
}
}
}
}
int A_start(int s){
priority_queue<heap> q;
q.push(heap(s,0));
while(!q.empty()){
heap h=q.top();
q.pop();
if(h.p==End){
if(k>1)
k--;
else
return h.d;
}
for(int i=head[h.p];i!=-1;i=e[i].next)
q.push( heap( e[i].to , h.d+e[i].cost ) ); // 核心
}
return -1;
}
int main() {
freopen("input.txt","r",stdin);
int i,j,a,b,t;
memset(head,-1,sizeof(head));
memset(rhead,-1,sizeof(rhead));
memset(vis,false,sizeof(vis));
scanf("%d%d",&n,&t);
while(t--){
scanf("%d%d%d",&i,&j,&a);
addEdge(i,j,a);
}
scanf("%d%d%d",&Start,&End,&k);
dij(End);
if(dis[Start]==INF){
puts("-1\n");
return 0;
}
if(Start==End)k++; // 题目要求
printf("%d\n",A_start(Start));
return 0;
}
本文介绍了如何利用A*启发式搜索算法解决图论中的K短路问题,通过实例详细解析了A*算法在poj2449问题中的具体应用和实现过程。
2982

被折叠的 条评论
为什么被折叠?



