题目大意:找出1~k短路
题解:x的估价函数
f(x)
取x到结束节点的最短路,这个是准确值,因此复杂度有保证
按广搜的方式扩展节点,每次优先扩展估价+实际最小的节点
第i次扩展到目标节点,代表找到了第i短路
我的收获:org
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<queue>
#define maxn 5010
#define maxm 201000
#define inf 1e12
using namespace std;
struct yts
{
int now;
double g;
};
double dis[maxn];
int q[maxn];
bool vis[maxn];
bool operator<(yts x,yts y)
{
return x.g+dis[x.now]>y.g+dis[y.now];
}
priority_queue<yts> Q;
int head[maxn],to[maxm],next[maxm];
double len[maxm],Len[maxm];
int Head[maxn],To[maxm],Next[maxm];
int n,m,num,ans,x,y,S,T,Num;
double e,z;
void addedge(int x,int y,double z)
{
num++;to[num]=y;len[num]=z;next[num]=head[x];head[x]=num;
}
void add(int x,int y,double z)
{
Num++;To[Num]=y;Len[Num]=z;Next[Num]=Head[x];Head[x]=Num;
}
void spfa()
{
for (int i=S;i<=T;i++) dis[i]=inf;
dis[T]=0;vis[T]=1;q[1]=T;
int l=0,r=1;
while (l!=r)
{
l++;if (l==maxn) l=0;
int x=q[l];
for (int p=Head[x];p;p=Next[p])
if (dis[x]+Len[p]<dis[To[p]])
{
dis[To[p]]=dis[x]+Len[p];
if (!vis[To[p]])
{
r++;if (r==maxn) r=0;
vis[To[p]]=1;q[r]=To[p];
}
}
vis[x]=0;
}
}
void Astar()
{
Q.push((yts){S,0});
while (!Q.empty())
{
yts x=Q.top();Q.pop();
if (x.now==T)
{
e-=x.g;
if (e<0) return;
ans++;
continue;
}
if (x.g+dis[x.now]>e) continue;
for (int p=head[x.now];p;p=next[p]) Q.push((yts){to[p],x.g+len[p]});
}
}
int main()
{
scanf("%d%d%lf",&n,&m,&e);
for (int i=1;i<=m;i++)
{
scanf("%d%d%lf",&x,&y,&z);
addedge(x,y,z);add(y,x,z);
}
S=1,T=n;
spfa();
Astar();
printf("%d\n",ans);
return 0;
}
本文介绍了一种利用A*算法寻找图中从起点到终点的前k条最短路径的方法。通过定义合适的估价函数并结合广度优先搜索的思想,确保了算法效率。代码实现了基于优先队列的节点扩展策略。
325

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



