poj 2449 Remmarguts' Date 启发式搜索 A*算法
做這個(gè)題算是學(xué)了學(xué)spfa算法,一開始感覺spfa和dij好像;dij找最小點(diǎn)松弛,spfa就是一個(gè)一個(gè)的松弛,松到不能松。
求S到T的第K短路
思路:這個(gè)算法的思路是從源點(diǎn)S優(yōu)雅的暴力跑bfs,用優(yōu)先隊(duì)列來(lái)裝跑的過程中點(diǎn)的位置以及跑的距離,優(yōu)先隊(duì)列按照來(lái)裝跑的距離最短的排序,然后隨著跑跑的距離就越來(lái)越長(zhǎng),那總會(huì)跑到T點(diǎn)吧,這個(gè)時(shí)候你的cnt+1,直到第k次跑到T點(diǎn)的時(shí)候就是第K短路了。看著很迷,但是為什么說(shuō)是優(yōu)雅呢,就是該算法的核心,A*就是Astar算法
1.首先,從終點(diǎn)T跑一邊Spfa,用數(shù)組d[ ]記錄每一個(gè)點(diǎn)到終點(diǎn)T的最短距離。
2.然后,從起點(diǎn)S跑bfs,邊跑邊記錄跑的距離F與位置now,優(yōu)雅的就是,當(dāng)我們每次跑到一個(gè)位置的時(shí)候,其實(shí)從位置now到T點(diǎn)的最短的距離G又確定了,G=F+d[now],然后我們結(jié)構(gòu)體裝進(jìn)去位置,已經(jīng)跑的距離,從該點(diǎn)跑到T點(diǎn)的最短距離{now,F,G},并且按照G點(diǎn)排序,當(dāng)我們走到終點(diǎn)now=T,這個(gè)時(shí)候就是第一次跑到G點(diǎn)的時(shí)候,那么F就是第一短的距離,那么跑到第k次終點(diǎn)T,此時(shí)的F就是第K短路。
參考博客:https://blog.csdn.net/z_mendez/article/details/47057461? 超級(jí)清晰的介紹
代碼如下:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<set>
#include<stack>
#include<vector>
#include<map>
#include<queue>
#define myself i,l,r
#define lson i<<1
#define rson i<<1|1
#define Lson i<<1,l,mid
#define Rson i<<1|1,mid+1,r
#define half (l+r)/2
#define inff 0x3f3f3f3f
#define lowbit(x) x&(-x)
#define me(a,b) memset(a,b,sizeof(a))
#define min4(a,b,c,d) min(min(a,b),min(c,d))
#define min3(x,y,z) min(min(x,y),min(y,z))
#define max4(a,b,c,d) max(max(a,b),max(c,d))
#define max3(x,y,z) max(max(x,y),max(y,z))
typedef long long ll;
const double eqs=1e-9;
const double pi=acos(-1.0);
const double E=2.718281828459;
using namespace std;
const int maxm=1e5+5;
const int maxn=1005;
int d[maxn],head[maxn],rhead[maxn];
int vis[maxn],n,m,t,k;
struct Edge
{int to,p,val;
}edge[maxm<<1],redge[maxm<<1];
struct node
{int now,g,f;bool friend operator<(node s,node e){if(s.f==e.f) return s.g>e.g;return s.f>e.f;}
};
void init()
{for(int i=0;i<=n;i++){d[i]=inff;head[i]=rhead[i]=-1;vis[i]=0;}
}
void add(int u,int v,int val,int sign)
{redge[sign]=Edge{u,rhead[v],val};rhead[v]=sign;edge[sign]=Edge{v,head[u],val};head[u]=sign;
}
void Spfa(int u)
{queue<int> q;d[u]=0;q.push(u);while(!q.empty()){u=q.front();q.pop();vis[u]=0;for(int i=rhead[u];~i;i=redge[i].p){int v=redge[i].to;if(d[v]>d[u]+redge[i].val){d[v]=d[u]+redge[i].val;if(!vis[v]){q.push(v);vis[v]=1;}}}}
}
int Astar(int s)
{priority_queue<node>q;int cnt=0;if(s==t) k++;///如果是起點(diǎn)等于終點(diǎn)k++if(d[s]==inff) return -1;node a,next;a=node{s,0,d[s]};q.push(a);while(!q.empty()){a=q.top();q.pop();if(a.now==t){cnt++;if(cnt==k)return a.g;}for(int i=head[a.now];i!=-1;i=edge[i].p){next.now=edge[i].to;next.g=a.g+edge[i].val;next.f=next.g+d[next.now];q.push(next);}}return -1;
}
int main()
{int s,x,y,z;while(scanf("%d%d",&n,&m)!=EOF){init();for(int i=0;i<m;i++){scanf("%d%d%d",&x,&y,&z);add(x,y,z,i);}scanf("%d%d%d",&s,&t,&k);Spfa(t);printf("%d\n",Astar(s));}return 0;
}
?
總結(jié)
以上是生活随笔為你收集整理的poj 2449 Remmarguts' Date 启发式搜索 A*算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ - 2337 Catenyms
- 下一篇: 欧拉函数,欧拉筛