k短路算法
k短路算法
求解k短路用到了A* 算法,A* ( A star )算法,又称启发式搜索算法,与之相对的,dfs与bfs都成为盲目型搜索;即为带有估价函数的优先队列BFS称为A*算法。
该算法的核心思想为设计一个估价函数,估价函数需要满足下面几个准则:
1:设当前状态state到目标状态所需的估计值为\(f(state)\)。
2:在未来的搜索中,实际求出的从当前状态state到目标状态的最小代价为\(g(state)\)。
3:对于任意的\(state\),应该有\(f(state)<=g(state)\)。
之后每次取出“当前代价+未来估价最小的状态,最终更新到目标状态上,就能得到最优解。
A*算法的应用非常广,被广泛应用于最优路径求解和一些策略设计问题中。
首先跑一下Dijkstra或者SPFA反向求一下终点到各个点的最短路,然后A*求出k短路,上代码:
#include<cstdio> #include<cstring> #include<queue> using namespace std; const int maxn=1e5+10; const int inf=0x3f3f3f3f; int head[maxn],head1[maxn],tot,tot1; int n,m,s,t,k,dis[maxn]; struct Edge{ int nex,to,val; }edge[maxn],edge1[maxn]; struct node{ int to,f,g; //估价函数和实际代价 friend bool operator <(const node& a,const node& b){ if(a.f==b.f) return a.g>b.g; return a.f>b.f; } }now,temp; bool vis[maxn]; void add(int from,int to,int val) { edge[++tot].to=to; edge[tot].val=val; edge[tot].nex=head[from]; head[from]=tot; } void add1(int from,int to,int val) { edge1[++tot1].to=to; edge1[tot1].val=val; edge1[tot1].nex=head1[from]; head1[from]=tot1; } queue<int> q; bool spfa(int s) { for(int i=1;i<=n;++i){ dis[i]=inf; vis[i]=false; } vis[s]=1; dis[s]=0; while(!q.empty()) q.pop(); q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); vis[u] = 0; for(int i=head1[u];i!=-1;i=edge1[i].nex){ int v=edge1[i].to; if(dis[v]>dis[u]+edge[i].val){ dis[v]=dis[u]+edge[i].val; if(vis[v]) continue; vis[v] = 1; q.push(v); } } } return true; } priority_queue<node> que; int A_star() { int cnt=0; while(!que.empty()) que.pop(); if(!spfa(t)||dis[s]==inf) return -1; if(s==t) ++k; //起点跟终点相同,不能算dis=0这一条 now.to=s; now.g=0; now.f=now.g+dis[now.to]; que.push(now); while(!que.empty()){ now = que.top(); que.pop(); if(now.to==t) cnt++; if(cnt==k) return now.g; for(int i=head[now.to];i!=-1;i=edge[i].nex){ temp.to=edge[i].to; temp.g=now.g+edge[i].val; temp.f=temp.g+dis[temp.to]; que.push(temp); } } return -1; } int main() { while(scanf("%d %d",&n,&m)==2) { for(int i=1;i<=n;++i){ head[i]=head1[i]=-1; } tot=tot1=0; for(int i=1;i<=m;++i){ int a,b,val; scanf("%d %d %d",&a,&b,&val); add(a,b,val); add1(b,a,val); } scanf("%d %d %d",&s,&t,&k); printf("%d\n",A_star()); } }
相关推荐
湾区人工智能 2020-11-20
Pokemogo 2020-11-16
baijingjing 2020-11-16
baijingjing 2020-11-15
Site 2020-11-07
lwnylslwnyls 2020-11-06
justaipanda 2020-11-05
MachineIntellect 2020-11-02
xueyuediana 2020-10-30
GeraldJones 2020-10-30
Tips 2020-10-29
baijingjing 2020-10-28
baijingjing 2020-10-27
硕鼠 2020-10-26
playoffs 2020-10-26
scuyxi 2020-10-25
playoffs 2020-10-25
yise001 2020-10-23