题意:
经典的第k短路,A*算法的经典应用之一。
分析:
A*,已走的路程g+到终点的最短距离为启发函数,搜索过程中不判重,第k次到t节点时就求出了第k短路。
代码:
//poj 2449
//sep9
#include <iostream>
#include <queue>
using namespace std;
const int maxN=1024;
const int maxM=100024;
int n,m,s,t,k,e,ne;
int head[maxN],nhead[maxN],dis[maxN],inq[maxN];
struct EDGE
{
int v,w,nxt;
}edge[maxM],nedge[maxM];
struct NODE
{
int ids,g;
bool operator < (const NODE &a) const{
return g+dis[ids]>a.g+dis[a.ids];
}
};
void addedge(int a,int b,int c)
{
edge[e].v=b,edge[e].w=c,edge[e].nxt=head[a],head[a]=e++;
nedge[ne].v=a,nedge[ne].w=c,nedge[ne].nxt=nhead[b],nhead[b]=ne++;
}
void spfa()
{
queue<int> q;
for(int i=1;i<=n;++i)
dis[i]=INT_MAX;
memset(inq,0,sizeof(inq));
q.push(t);
inq[t]=1;
dis[t]=0;
while(!q.empty()){
int a=q.front();q.pop();
inq[a]=0;
for(int i=nhead[a];i!=-1;i=nedge[i].nxt){
int b=nedge[i].v,w=nedge[i].w;
if(dis[a]+w<dis[b]){
dis[b]=dis[a]+w;
if(!inq[b])
q.push(b);
}
}
}
}
int astar()
{
priority_queue<NODE> q;
NODE x;
x.ids=s,x.g=0;
q.push(x);
while(!q.empty()){
x=q.top();q.pop();
if(x.ids==t){
if(--k==0)
return x.g;
}
for(int i=head[x.ids];i!=-1;i=edge[i].nxt){
int v=edge[i].v,w=edge[i].w;
if(dis[v]==INT_MAX) continue;
NODE y;
y.ids=v,y.g=x.g+w;
q.push(y);
}
}
return -1;
}
int main()
{
scanf("%d%d",&n,&m);
e=0,ne=0;
memset(head,-1,sizeof(head));
memset(nhead,-1,sizeof(nhead));
while(m--){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
addedge(a,b,c);
}
scanf("%d%d%d",&s,&t,&k);
if(s==t) ++k;
spfa();
printf("%d",astar());
return 0;
} poj 2449 Remmarguts' Date A*+spfa求第k短路
原文地址:http://blog.csdn.net/sepnine/article/details/46242495