【题目链接】
https://www.lydsy.com/JudgeOnline/problem.php?id=1598
【题解】
A*模板题。
【代码】
/* - - - - - - - - - - - - - - -
User : VanishD
problem : [bzoj1598]
Points : K-th shortest road -- Yen algorithm
- - - - - - - - - - - - - - - */
# include <bits/stdc++.h>
# define ll long long
# define inf 0x3f3f3f3f
# define N 1010
# define K 110
# define M 100100
using namespace std;
typedef vector <int> vt;
int read(){
int tmp = 0, fh = 1; char ch = getchar();
while (ch < '0' || ch > '9'){ if (ch == '-') fh = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9'){ tmp = tmp * 10 + ch - '0'; ch = getchar(); }
return tmp * fh;
}
struct Node{
int vote, id;
vt rd, d;
}now, nex;
struct Edge{
int data, next, vote;
}e[M];
vt rd[K], eg[N], vg[N];
priority_queue <Node> hp;
int n, m, k, S, T, dis[N], use[N], tag[N], q[N], head[N], frm[N], place, ans[K], eu[M], ev[M], ew[M];
set <vt> mp;
void build(int u, int v, int w){
e[++place].data = v; e[place].next = head[u]; head[u] = place; e[place].vote = w;
}
bool operator < (Node x, Node y){
if (x.vote > y.vote) return true;
if (x.vote < y.vote) return false;
for (unsigned j = 0; ; j++){
if (j == y.rd.size() && j != x.rd.size()) return true;
if (j == x.rd.size() && j != y.rd.size()) return false;
if (j == y.rd.size() && j == x.rd.size()){
if (x.id > y.id) return true;
else return false;
}
if (x.rd[j] > y.rd[j]) return true;
if (x.rd[j] < y.rd[j]) return false;
}
}
bool operator < (vt x, vt y){
for (unsigned j = 0; ; j++){
if (j == y.size()) return true;
if (j == x.size()) return false;
if (x[j] > y[j]) return true;
if (x[j] < y[j]) return false;
}
}
void spfa(int T){
memset(dis, inf, sizeof(dis));
dis[T] = 0, q[1] = T;
memset(use, 0, sizeof(use));
int pl = 1, pr = 1; use[T] = true;
while (pl <= pr){
int x = q[(pl++) % n];
for (int ed = head[x]; ed != 0; ed = e[ed].next)
if (tag[e[ed].data] == false){
if (dis[e[ed].data] > dis[x] + e[ed].vote || (dis[e[ed].data] == dis[x] + e[ed].vote && x < eu[frm[e[ed].data]])){
dis[e[ed].data] = dis[x] + e[ed].vote;
frm[e[ed].data] = ed;
if (use[e[ed].data] == false){
use[e[ed].data] = true;
q[(++pr) % n] = e[ed].data;
}
}
}
use[x] = false;
}
}
bool cmp(int x, int vx, int y, int vy){
return vx < vy || (vx == vy && x < y);
}
int main(){
// freopen("bzoj1598.in", "r", stdin);
// freopen("bzoj1598.out", "w", stdout);
n = read(), m = read(), k = read(), S = n, T = 1;
for (int i = 1; i <= m; i++){
eu[i] = read(), ev[i] = read(), ew[i] = read();
if (eu[i] < ev[i]) swap(eu[i], ev[i]);
build(ev[i], eu[i], ew[i]);
eg[eu[i]].push_back(i);
}
spfa(T);
nex.id = 0, nex.vote = dis[S];
int p = S, tot = 0;
while (p != T){
nex.rd.push_back(frm[p]);
nex.d.push_back(tot += dis[p] - dis[ev[frm[p]]]);
p = ev[frm[p]];
}
hp.push(nex);
memset(ans, -1, sizeof(ans));
for (int i = 1; i <= k; i++){
if (hp.size() == 0) break;
now = hp.top();
hp.pop();
rd[i].clear();
for (unsigned j = 0; j < now.rd.size(); j++)
rd[i].push_back(now.rd[j]);
if (mp.find(rd[i]) != mp.end()){
i--; continue;
}
ans[i] = now.vote;
mp.insert(rd[i]);
for (unsigned j = now.id; j < now.rd.size(); j++){
int u = eu[now.rd[j]], v = ev[now.rd[j]], mni = 0, mn = inf, np;
for (unsigned t = 0; t < eg[u].size(); t++){
int tmpi = ev[eg[u][t]], tmp = dis[ev[eg[u][t]]] + ew[eg[u][t]];
if (j != 0) tmp += now.d[j - 1];
if (cmp(v, dis[v] + now.d[j], tmpi, tmp) == true && now.rd[j] != eg[u][t])
if (cmp(mni, mn, tmpi, tmp) == false)
mni = tmpi, mn = tmp, np = eg[u][t];
}
if (mni != 0){
nex.id = j; nex.vote = mn;
nex.rd.clear(); nex.d.clear();
for (unsigned k = 0; k < j; k++)
nex.rd.push_back(now.rd[k]), nex.d.push_back(now.d[k]);
int tot = (j == 0) ? 0 : nex.d[j - 1], p = mni;
nex.rd.push_back(np), nex.d.push_back(tot += ew[np]);
while (p != T){
nex.rd.push_back(frm[p]);
nex.d.push_back(tot += dis[p] - dis[ev[frm[p]]]);
p = ev[frm[p]];
}
hp.push(nex);
}
}
}
for (int i = 1; i <= k; i++)
printf("%d\n", ans[i]);
return 0;
}