版权声明:本文为博主原创文章,转载请预先通知博主(〃▽〃)。 https://blog.csdn.net/m0_37624640/article/details/83417772
做法:
- A*算法(最佳搜索算法,基于启发式)(人工智能课上也学习了)
- 讲解:
- 求图的第K短路(A*算法与最短路的应用)
- A* && 第k短路详解 (详尽)
- 说一下注意的地方:
- 用逆向建图,用dijkstra跑一边是为了求出g(i),因为g(i)为结点i到终点的实际距离。所以我们逆向跑一边,就得到了终点到各个点i的距离,就得了g(i)。
- 存个板子~
AC代码: 基于邻接表
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <string>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <stack>
using namespace std;
#define IO ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define pb(x) push_back(x)
#define sz(x) (int)(x).size()
#define sc(x) scanf("%d",&x)
#define abs(x) ((x)<0 ? -(x) : x)
#define all(x) x.begin(),x.end()
#define mk(x,y) make_pair(x,y)
#define fin freopen("in.txt","r",stdin)
#define fout freopen("out.txt","w",stdout)
typedef long long ll;
typedef pair<int,int> P;
const int mod = 1e9+7;
const double PI = 4*atan(1.0);
const int maxm = 1e8+5;
const int maxn = 1e3+10;
const int INF = 0x3f3f3f3f;
const ll LINF = 1ll<<62;
struct node
{
int to,w;
node(int to,int w){
this->to = to;
this->w = w;
}
};
vector<node> edge[maxn],_edge[maxn];
struct anode
{
int h,g,id;
anode(int h,int g,int id){
this->h = h;
this->g = g;
this->id = id;
}
bool operator < (anode y)const{
return h+g > y.h+y.g;
}
};
int n,m,s,t,k,q;
int dist[maxn];
void addedge(int u,int v,int w)
{
edge[u].push_back(node(v,w));
_edge[v].push_back(node(u,w));
}
void dij(int s)
{
priority_queue<P,vector<P>,greater<P> >q;
// memset(dist,INF,sizeof(dist));
fill(dist,dist+n+1,INF);
dist[s] = 0;
q.push(P(0,s));
while(!q.empty())
{
P p = q.top();q.pop();
int v = p.second;
if(dist[v] < p.first) continue;
for(int i=0;i<(int)_edge[v].size();i++)
{
node e = _edge[v][i];
if(dist[e.to] > dist[v]+e.w)
{
dist[e.to] = dist[v]+e.w;
q.push(P(dist[e.to],e.to));
}
}
}
}
int Astar(int s,int t)
{
if(dist[s]==INF) return -1;//判断有无最短路
priority_queue<anode> qa;
qa.push(anode(0,dist[s],s));
int cnt = 0;
while(!qa.empty())
{
anode u = qa.top();qa.pop();
if(u.id == t) ++cnt;
if(cnt>=k) return u.h;
if(cnt<k && u.h>q) return -1; //剪枝
for(int i=0;i<(int)edge[u.id].size();i++)
{
node v = edge[u.id][i];
qa.push(anode(u.h+v.w,dist[v.to],v.to));
}
}
return -1;
}
int main()
{
// fin;
// IO;
while(~scanf("%d %d",&n,&m))
{
for(int i=0;i<=n;i++){
edge[i].clear();
_edge[i].clear();
}
sc(s);sc(t);sc(k);sc(q);
for(int i=1;i<=m;i++)
{
int u,v,w;
sc(u);sc(v);sc(w);
addedge(u,v,w);
}
//if(s == t) k++;
dij(t);
int ans = Astar(s,t);
if(ans<=q && ans!=-1) printf("yareyaredawa\n");
else printf("Whitesnake!\n");
}
return 0;
}
AC代码: 基于链式前向星
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <string>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <stack>
using namespace std;
#define IO ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define pb(x) push_back(x)
#define sz(x) (int)(x).size()
#define sc(x) scanf("%d",&x)
#define abs(x) ((x)<0 ? -(x) : x)
#define all(x) x.begin(),x.end()
#define mk(x,y) make_pair(x,y)
#define fin freopen("in.txt","r",stdin)
#define fout freopen("out.txt","w",stdout)
typedef long long ll;
typedef pair<int,int> P;
const int mod = 1e9+7;
const int maxm = 1e8+5;
const int maxn = 1e4+10;
const int INF = 0x3f3f3f3f;
const ll LINF = 1ll<<62;
struct node
{
int to,nex;
int w;
};
node edge[maxn],_edge[maxn];
//vector<node> edge[maxn],_edge[maxn];
struct anode
{
int h,g,id;
anode(int h,int g,int id){
this->h = h;
this->g = g;
this->id = id;
}
bool operator < (anode y)const{
return h+g > y.h+y.g;
}
};
int n,m,s,t,k,q;
int dist[maxn];
int head[maxn],_head[maxn];
void addedge(int u,int v,int w,int i)
{
edge[i].to = v;
edge[i].w = w;
edge[i].nex = head[u];
head[u] = i;
_edge[i].to = u;
_edge[i].w = w;
_edge[i].nex = _head[v];
_head[v] = i;
}
void dij(int s)
{
priority_queue<P,vector<P>,greater<P> >q;
fill(dist,dist+n+1,INF);
dist[s] = 0;
q.push(P(0,s));
while(!q.empty())
{
P p = q.top();q.pop();
int u = p.second;
if(dist[u] < p.first) continue;
for(int i=_head[u];~i;i = _edge[i].nex)
{
int v = _edge[i].to;
if(dist[v] > dist[u]+_edge[i].w)
{
dist[v] = dist[u]+edge[i].w;
q.push(P(dist[v],v));
}
}
}
}
int Astar(int s,int t)
{
if(dist[s]==INF) return -1;//判断有无最短路
priority_queue<anode> qa;
qa.push(anode(0,dist[s],s));
int cnt = 0;
while(!qa.empty())
{
anode u = qa.top();qa.pop();
if(u.id == t) ++cnt;
if(cnt>=k) return u.h;
if(cnt<k && u.h>q) return -1; //剪枝
for(int i=head[u.id];~i;i = edge[i].nex)
{
int v = edge[i].to;
qa.push(anode(u.h+edge[i].w,dist[v],v));
}
}
return -1;
}
int main()
{
// fin;
// IO;
while(~scanf("%d %d",&n,&m))
{
memset(head,-1,sizeof(head));
memset(_head,-1,sizeof(_head));
sc(s);sc(t);sc(k);sc(q);
for(int i=1;i<=m;i++)
{
int u,v,w;
sc(u);sc(v);sc(w);
addedge(u,v,w,i);
}
//if(s == t) k++;
dij(t);
int ans = Astar(s,t);
if(ans<=q && ans!=-1) printf("yareyaredawa\n");
else printf("Whitesnake!\n");
}
return 0;
}