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; }