解题关键:k短路模板题,A*算法解决。
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> #include<queue> using namespace std; typedef long long ll; const int N=1e3+10; const int M=1e5+10; const int inf=1e9; struct edge{ int v,w,nxt; }e1[M],e2[M]; struct node{ int id;///当前节点编号 int f;//f表示经过当前节点的最短路,f=g+h int g;//g表示S->当前节点的最短路 node(int id=0,int f=0,int g=0):id(id),f(f),g(g){} bool operator<(const node &a)const{ if(f==a.f) return g>a.g; return f>a.f; } }; bool vis[N]; int tot,head1[N],head2[N],n,m,K; int dis[N];//dis[i]表示当前点i到终点T的最短路径 void add_edge(int u,int v,int w){ e1[tot].v=v;e1[tot].w=w;e1[tot].nxt=head1[u];head1[u]=tot; e2[tot].v=u;e2[tot].w=w;e2[tot].nxt=head2[v];head2[v]=tot; tot++; }//两个图 void spfa(int S){//更新每个点->n点的最短距离 queue<int>q; fill(dis,dis+n+1,inf); dis[S]=0; vis[S]=1; q.push(S); while(!q.empty()){ int x=q.front();q.pop(); vis[x]=0; for(int i=head2[x];~i;i=e2[i].nxt){ int v=e2[i].v,w=e2[i].w; if(dis[v]>dis[x]+w){ dis[v]=dis[x]+w; if(!vis[v]){ vis[v]=1; q.push(v); } } } } } int A_Star(int S,int T){ if(S==T) K++;//坑,题目要求必须走,s==t路程可能为0,所以K要加1 priority_queue<node>q; q.push(node(S,0,0)); int cnt=0; while(!q.empty()){ node h=q.top();q.pop(); if(h.id==T){ if(++cnt==K){ return h.f; } } for(int i=head1[h.id];~i;i=e1[i].nxt){ q.push(node(e1[i].v,h.g+e1[i].w+dis[e1[i].v],h.g+e1[i].w));//最短路更新k短路 } } return -1; } int main(){ memset(head1,-1,sizeof head1); memset(head2,-1,sizeof head2); scanf("%d%d",&n,&m); for(int i=1,x,y,z;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); add_edge(x,y,z); } int S,T; scanf("%d%d%d",&S,&T,&K); spfa(T);//预处理,反向遍历 int ans=A_Star(S,T); printf("%d ",ans); return 0; }