1 #include<iostream>
2 #include<algorithm>
3 #include<cstdio>
4 #include<cstring>
5 #include<queue>
6 using namespace std;
7 const int MAX_V = 1100;
8 const int MAX_E = 110000;
9 const int INF = 0x3f3f3f3f;
10
11 struct ENode
12 {
13 int to;
14 int w;
15 int Next;
16 };
17 ENode edegs[MAX_E];
18 ENode edegs1[MAX_E]; //存反图;
19 int Head[MAX_V], Head1[MAX_V], tnt, tnt1;
20 void Add_ENode (int a, int b, int w)
21 {
22 ++ tnt;
23 edegs[tnt].to= b;
24 edegs[tnt].w= w;
25 edegs[tnt].Next= Head[a];
26 Head[a]= tnt;
27 // ++ tnt; //无向图
28 // edegs[tnt].to= a;
29 // edegs[tnt].w= w;
30 // edegs[tnt].Next= Head[b];
31 // Head[b]= tnt;
32 }
33 void Add_ENode1 (int a, int b, int w)
34 {
35 /**建反向图*/
36 ++ tnt1;
37 edegs1[tnt1].to= b;
38 edegs1[tnt1].w= w;
39 edegs1[tnt1].Next= Head1[a];
40 Head1[a]= tnt1;
41 // ++ tnt1; //无向图
42 // edegs1[tnt1].to= a;
43 // edegs1[tnt1].w= w;
44 // edegs1[tnt1].Next= Head1[b];
45 // Head1[b]= tnt1;
46 }
47
48 int Dis[MAX_V];
49 bool visit[MAX_V]; //是否已经遍历过;
50 int que[MAX_V]; // 模拟队列;
51 int outque[MAX_V]; //记录每个点出队列的次数,防止有负边,保证无负边的图可以省略;
52 bool SPFA(int s, int n)
53 {
54 /**SPFA处理反向图,预处理出Dis[]*/
55 /*s:起点; n:点的总数*/
56 int iq; //队列中元素个数;
57 memset(Dis, INF, sizeof(Dis));
58 memset(visit, false, sizeof(visit));
59 memset(outque, 0, sizeof(outque));
60 iq= 0;
61 que[iq ++]= s;
62 visit[s]= true;
63 Dis[s]= 0;
64 int i= 0;
65 while (i< iq)
66 {
67 int u= que[i];
68 visit[u]= false;
69 outque[u] ++;
70 if (outque[u]> n) return false; //当一个点进出队列超过n 次,必然有负边存在;
71
72 for (int k= Head1[u]; k!= -1; k= edegs1[k].Next)
73 {
74 /*bfs,和Dijkstra相似*/
75 int v= edegs1[k].to;
76 if (Dis[v]> Dis[u]+ edegs1[k].w)
77 {
78 Dis[v]= Dis[u]+ edegs1[k].w;
79 if (! visit[v])
80 {
81 visit[v]= true;
82 que[iq ++]= v;
83 }
84 }
85 }
86 i ++;
87 }
88 return true;
89 }
90
91 struct Node
92 {
93 int from;
94 int g; //g表示到当前点的路径长度
95 int f; //f=g+dis dis表示当前点到终点的最短路径,即之前的预处理
96 bool operator < (const Node &r) const
97 {
98 if (r.f== f) return r.g- g< 0;
99 return r.f- f< 0;
100 }
101 };
102 int A_star (int s, int t, int n, int k)
103 {
104 Node e, ne;
105 int cnt= 0;
106 priority_queue<Node> que;
107 if (s== t) k ++;
108 if (Dis[s]== INF) return -1;
109 e.from= s;
110 e.g= 0;
111 e.f= e.g+ Dis[e.from];
112 que.push(e);
113 while (! que.empty())
114 {
115 e= que.top();
116 que.pop();
117 if (e.from== t) cnt ++;
118 if (cnt== k) return e.g;
119 for (int i= Head[e.from]; i!= -1; i= edegs[i].Next)
120 {
121 ne.from= edegs[i].to;
122 ne.g= e.g+ edegs[i].w;
123 ne.f= ne.g+ Dis[ne.from];
124 que.push(ne);
125 }
126 }
127 return -1;
128 }
129
130 void into()
131 {
132 /**初始化*/
133 memset(Head,-1,sizeof(Head));
134 memset(Head1,-1,sizeof(Head1));
135 tnt= -1; tnt1= -1;
136 }
137
138 int main()
139 {
140 int n, m, k;
141 int a, b, w;
142 while (~ scanf("%d %d %d", &n, &m, &k))
143 {
144 into();
145 for (int i= 0; i< m; i ++)
146 {
147 scanf("%d %d %d", &a, &b, &w);
148 Add_ENode(a, b, w);
149 Add_ENode1(b, a, w); //建反图
150 }
151 SPFA(n, n); //处理出从终点到其他点的最短路径距离;
152 int far= A_star(1, n, n, k);
153 printf("%d\n", far);
154 }
155 return 0;
156 }