//poj2449 求第k短路
/*
一个最简单的想法是改造dijkstra算法,一个点可以多次进入优先队列,
统计终点第k次出队时的路径即可。
但这样等到第k次时状态数太多,无法承受。
于是使用astar算法思想对其进行改进。优先队列维护的是f(x)+g(x)的
值最小,其中g(x)是当前点到终点的最短路长度,而f(x)是从起点走到目前
点的路径。这样可以加速找到第k次出队的k点。
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
#define ll long long 
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define frr(i,a,b) for(int i=a;i>=b;i--)
#define ms(a,b) memset(a,b,sizeof(a))
#define scfd(a) scanf("%d",a)
#define scflf(a) scanf("%lf",a)
#define scfs(a) scanf("%s",a)
#define ptfd(a) printf("%d\n",a)
#define ptfs(a) printf("%s\n",a)
#define showd(a,b) printf(a"=%d\n",b)
#define showlf(a,b) printf(a"=%lf\n",b)
#define shows(a,b) printf(a"=%s\n",b)
#define mmcp(a,b) memcpy(a,b,sizeof(b))
#define pb(a) push_back(a)
const int MAXN=1005;
const int MAXM=100005;
int n,m,k;

int dr[MAXN];
struct edge{
	int f,t;
	int d;
};
struct point{
	int n;
	int d;
	bool operator<(const point &a)const{
		return d+dr[n]>a.d+dr[a.n];
	}
};
priority_queue<point>qq;
struct k_th{
	int s,t;
	vector<int>g[MAXN];
	vector<int>gr[MAXN];
	vector<edge>e;
	vector<edge>er;
	void init(){
		fr(i,0,MAXN-1){
			g[i].clear();
			gr[i].clear();
		}
		e.clear();
		er.clear();
	}
	void add_edge(int f,int t,int d){
		e.push_back((edge){f,t,d});
		er.push_back((edge){t,f,d});
		g[f].push_back(e.size()-1);
		gr[t].push_back(er.size()-1);
	}
	bool check(){
		fr(i,0,MAXN-1)
			dr[i]=214748360;
		dr[t]=0;
		queue<int>q;
		q.push(t);
		bool vis[MAXN];
		ms(vis,false);
		vis[t]=true;
		bool viss=false;
		while(!q.empty()){
			int now=q.front();
			q.pop();
			//cout<<"now="<<now<<endl;
			vis[now]=false;
			if(now==s)
				viss=true;
			int size=gr[now].size();
			//cout<<"size="<<size<<endl;
			fr(i,0,size-1)
				if(dr[er[gr[now][i]].t]>dr[now]+er[gr[now][i]].d){
					dr[er[gr[now][i]].t]=dr[now]+er[gr[now][i]].d;
					if(!vis[er[gr[now][i]].t]){
						q.push(er[gr[now][i]].t);
						vis[er[gr[now][i]].t]=true;
					}
				}
		}
		return viss;
	}
	int solve(){
		
		qq.push((point){s,0});
		int cnt=0;
		while(!qq.empty()){
			point now=qq.top();
			qq.pop();
			if(now.n==t){
				cnt++;
				if(cnt==k)
					return now.d;
			}
			int size=g[now.n].size();
			fr(i,0,size-1){
				edge ne=e[g[now.n][i]];
				qq.push((point){ne.t,now.d+ne.d});
			}
		}
		return -1;
	}
}kth;
int main(){
	ios::sync_with_stdio(false);
	while(cin>>n>>m){
		while(qq.size())
			qq.pop();
		kth.init();

		fr(i,1,m){
			int a,b,c;
			cin>>a>>b>>c;
			kth.add_edge(a,b,c);
		}
		cin>>kth.s>>kth.t>>k;
		if(kth.s==kth.t)
			k++;
		if(!kth.check())
			cout<<"-1"<<endl;
		else
			cout<<kth.solve()<<endl;
	}
	return 0;
}

 posted on 2017-09-22 17:03  cylcy  阅读(93)  评论(0编辑  收藏  举报