A*算法還是比較有意思的,本來以爲就是個搜索加減枝,現在看來是有複雜度保證的
我們到一個狀態後,處理出當前狀態的估價函數,每次選擇估價函數最小的來更新
估價函數g(n)的選取,若g(n)=實際值時,是有時間複雜度保證的,並且每次得到的答案一定是當前的最優解
bfs就是一個特殊的A*算法
這裏的估價函數g(i)可以設置成爲從T點到i點的最短路,每次用優先隊列選估價最小的那個點更新
#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;
}