嘛,这个东西挺好理解的,就相当于动态维护一个状态空间,然后当终点出来K次后就是答案。。。
但这样空间会炸,于是要想办法怎么快速接近这个k次终点,于是乎,再加上当前点到终点的距离,就可以缩小状态空间了。。。
#include<bits/stdc++.h>
#define MAXN 1005
#define maxn 100005
using namespace std;
int n,m,s,t,k,js;
int h[MAXN],h2[MAXN],tot,tot2,f[MAXN],vis[MAXN];
struct node{
int from,to,cost,next;
}e[maxn],e2[maxn];
struct node2{
int x,y,z;
bool operator<(const node2& a) const
{
return y + z > a.y + a.z;
}
};
void init(){
js = 0;
tot = tot2 = (-1);
memset(h , -1 , sizeof(h));
memset(h2 , -1 , sizeof(h2));
memset(f , 0x7f , sizeof(f));
memset(vis , -1 , sizeof(vis));
}
void add(int x,int y,int z){
tot++;
e[tot].from = x;
e[tot].to = y;
e[tot].cost = z;
e[tot].next = h[x];
h[x] = tot;
}
void add2(int x,int y,int z){
tot2++;
e2[tot2].from = x;
e2[tot2].to = y;
e2[tot2].cost = z;
e2[tot2].next = h2[x];
h2[x] = tot2;
}
void ycl(){
queue<int>q;
q.push(t);
vis[t] = 1;
f[t] = 0;
while(!q.empty()){
int u = q.front();
vis[u] = -1;
q.pop();
for(int i = h2[u] ; i != (-1) ; i = e2[i].next){
if(f[e2[i].to]>f[u] + e2[i].cost){
f[e2[i].to]=f[u] + e2[i].cost;
if(vis[e2[i].to] == (-1)){
vis[e2[i].to] = 1;
q.push(e2[i].to);
}
}
}
}
}
void solve(){
priority_queue<node2> q;
q.push((node2){s , 0 , 0});
while(!q.empty()){
node2 u = q.top();
q.pop();
if(u.x == t)js++;
if(js == k){cout<<u.y<<endl;exit(0);}
for(int i = h[u.x] ; i != (-1) ; i = e[i].next){
q.push((node2){e[i].to , u.y + e[i].cost , f[u.x]});
}
}
}
int main(){
init();
cin>>n>>m;
for(int i = 1 ; i <= m ; i++){
int x,y,z;cin>>x>>y>>z;
add(x , y , z);
add2(y , x , z);
}
cin>>s>>t>>k;
if(s == t)js--;
ycl();
if(f[s] > 9999999 || m==0){
cout<<-1<<endl;
exit(0);
}
solve();
cout<<-1<<endl;
exit(0);
}