题意:给一个有向图,判断其k短路是否超过T。
K短路是A*算法的应用,关于A*算法详解:A星算法详解,了解了A*算法详解后,就可以再看A*算法在K短路上的运用:K短路算法详解,看完这两篇详解后,这题就很容易了。先用迪杰斯特拉算法求出h数组,即终点到每个点的最短路,然后用优先队列根据g+h的和(数越小越优先)搜索最短路,若搜到终点k次,那么第k次的g值就是答案。
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1005;
const long long inf=1e15;
struct node
{
int u;
ll g,h;
node(int u,int g,int h):u(u),g(g),h(h){}
bool operator<(const node& t)const
{
return g+h>t.g+t.h;
};
};
ll d[maxn];
int vis[maxn],n,m,k,s,t,limit;
vector<int>G2[maxn],dis2[maxn],G[maxn],dis[maxn];
void init()
{
for(int i=1;i<=n;i++)
G2[i].clear(),dis2[i].clear(),G[i].clear(),dis[i].clear();
}
void dij()
{
priority_queue<node>q;
for(int i=1;i<=n;i++)d[i]=inf,vis[i]=0;
d[t]=0;
q.push(node(t,0,0));
while(!q.empty())
{
node no=q.top();q.pop();
int u=no.u;
if(vis[u])continue;
vis[u]=1;
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(d[v]>d[u]+dis[u][i])
{
d[v]=d[u]+dis[u][i];
q.push(node(v,0,d[v]));
}
}
}
}
ll Astar()
{
memset(vis,0,sizeof(vis));
priority_queue<node>q;
q.push(node(s,0,d[s]));
if(d[s]==inf)return inf;
while(!q.empty())
{
node no=q.top();q.pop();
int u=no.u;
vis[u]++;
if(vis[t]>=k)return no.g;
if(vis[u]>k)continue;
for(int i=0;i<G2[u].size();i++)
{
int v=G2[u][i];
q.push(node(v,no.g+dis2[u][i],d[v]));
}
}
return inf;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
int u,v,w;
init();
scanf("%d%d%d%d",&s,&t,&k,&limit);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
G[v].push_back(u);
dis[v].push_back(w);
G2[u].push_back(v);
dis2[u].push_back(w);
}
dij();
ll ans=Astar();
if(ans<=limit)puts("yareyaredawa");
else puts("Whitesnake!");
}
}