2018 icpc瀋陽站網路賽 D. Made In Heaven k短路
阿新 • • 發佈:2018-12-09
題意:給一個有向圖,判斷其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!"); } }