poj 2449
给出一个图,求s到t的第k短路
解法:
首先想到搜索,然后发现A*算法的性质是满足的
1> h(i)<=h(j)+cost(i,j)
2> h(i)<=h(i)* [h(i)*表示到达目标状态的实际值]
令估价函数h(i)=h(i)*=dist(i->t)
然后从s开始搜索出第k短路
另外要特判s=t的情况
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXN 1005
#define MAXM 100005
#define SIZE 1000005
#define INF64 200000000
int n,m;
int s,t,k;
struct edge{int v,w,next;}mp[MAXM]={0},mps[MAXM]={0};int ml=0,mls=0;
int head[MAXN]={0};int heads[MAXN]={0};
struct node{int u;long long cost;}heap[SIZE]={0},emp,swap;int hl=0;
int line[MAXN]={0};int f,r;
long long dist[MAXN]={0};
int cnt[MAXN]={0};
char flag[MAXN]={0};
void newedge(int u0,int v0,int w0)
{
++ml;
mp[ml].v=v0;
mp[ml].w=w0;
mp[ml].next=head[u0];
head[u0]=ml;
}
void newedges(int u0,int v0,int w0)
{
++mls;
mps[mls].v=v0;
mps[mls].w=w0;
mps[mls].next=heads[u0];
heads[u0]=mls;
}
void spfa()
{
int i,c,p;long long tmp;
for(i=1;i<=n;i++)
dist[i]=INF64;
dist[t]=0;
f=r=0;line[r++]=t;
while(f!=r)
{
c=line[f];f=(f+1)%MAXN;flag[c]=0;
for(i=heads[c];i;i=mps[i].next)
{
p=mps[i].v;
tmp=dist[c]+mps[i].w;
if(tmp<dist[p])
{
dist[p]=tmp;
if(!flag[p])
{
flag[p]=1;
if(tmp<dist[line[f]])
{
f=(f-1+MAXN)%MAXN;
line[f]=p;
}
else
{
line[r]=p;
r=(r+1)%MAXN;
}
}
}
}
}
}
void adjust(int a)
{
int min=a;
int l=a<<1,r=l+1;
if(l<=hl && heap[l].cost<heap[min].cost)min=l;
if(r<=hl && heap[r].cost<heap[min].cost)min=r;
if(min!=a)
{
swap=heap[a];
heap[a]=heap[min];
heap[min]=swap;
adjust(min);
}
}
void update(int a)
{
int fa=a/2;
if(fa)
{
if(heap[fa].cost>heap[a].cost)
{
swap=heap[fa];
heap[fa]=heap[a];
heap[a]=swap;
update(fa);
}
}
}
long long Astar()
{
struct node c;
int p,q,i;
if(dist[s]==INF64)return -1;
++hl;heap[hl].u=s,heap[hl].cost=dist[s];
while(hl)
{
c=heap[1];
heap[1]=heap[hl];
heap[hl]=emp;
hl--;
if(hl)adjust(1);
cnt[c.u]++;
if(c.u==t && cnt[c.u]==k)return c.cost;
for(i=head[c.u];i;i=mp[i].next)
{
p=mp[i].v;
if(cnt[p]<k)
{
++hl;heap[hl].u=p,heap[hl].cost=c.cost+mp[i].w-dist[c.u]+dist[p];
update(hl);
}
}
}
return -1;
}
int main()
{
int i,a,b,l;
#ifndef ONLINE_JUDGE
freopen("poj2449.in","r",stdin);
freopen("poj2449.out","w",stdout);
#endif
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&l);
newedge(a,b,l);
newedges(b,a,l);
}
scanf("%d%d%d",&s,&t,&k);
spfa();
if(s==t)k++;
printf("%lld",Astar());
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}