先用Dijkstra计算出1到i的最短路d[i]。再dfs时如果 d[u] + w == d[v] 时就一直继续向下搜索。这些边都可以保留
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
#include<vector>
#include<string>
#include<fstream>
using namespace std;
#define rep(i, a, n) for(int i = a; i <= n; ++ i);
#define per(i, a, n) for(int i = n; i >= a; -- i);
typedef long long ll;
typedef pair<ll, int> PII;
const int N = 300100;
const int mod = 998244353;
const double Pi = acos(- 1.0);
const ll INF = 1e18;
const int G = 3, Gi = 332748118;
ll qpow(ll a, ll b) { ll res = 1; while(b){ if(b & 1) res = (res * a) % mod; a = (a * a) % mod; b >>= 1;} return res; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a * b / gcd(a, b);}
bool cmp(int a, int b){ return a > b;}
//
int n, m, k;
int head[N], cnt = 0;
int nxt[N << 1], to[N << 1]; ll c[N << 1];
bool vis[N];
ll d[N];
vector<int> res;
map<ll, int> mp;
inline void add(ll u, ll v, ll w){
to[cnt] = v, c[cnt] = w, nxt[cnt] = head[u], head[u] = cnt ++;
to[cnt] = u, c[cnt] = w, nxt[cnt] = head[v], head[v] = cnt ++;
}
void Dijkstra(int st){
priority_queue<PII, vector<PII>, greater<PII> > q;
for(int i = 0; i <= n + 1; ++ i) d[i] = INF;
d[st] = 0;
q.push(PII(0, st));
while(q.size()){
int u = q.top().second; ll w1 = q.top().first ; q.pop();
if(w1 != d[u]) continue;
for(int i = head[u]; i != -1; i = nxt[i]){
int v = to[i]; ll w2 = c[i];
if(d[v] > d[u] + w2){
d[v] = d[u] + w2;
q.push(PII(d[v], v));
}
}
}
}
void dfs(ll u){
for(int i = head[u]; i != -1; i = nxt[i]){
ll v = to[i]; ll w = c[i];
if(vis[v]) continue;
if(d[u] + w == d[v]){
vis[v] = true;
res.push_back(mp[u * N + v]);
dfs(v);
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
cnt = 0;
for(int i = 0; i <= n; ++ i) vis[i] = false, head[i] = -1;
for(int i = 1; i <= m; ++ i){
ll x, y, z; scanf("%lld%lld%lld",&x,&y,&z);
add(x, y, z);
mp[x * N + y] = mp[y * N + x] = i;
}
Dijkstra(1);
vis[1] = true;
dfs(1);
int tt = res.size();
printf("%d
",min(tt, k));
if(tt < k){
for(int i = 0; i < tt; ++ i) printf("%d ",res[i]);
int num = k - tt;
for(int i = 1; i <= n; ++ i){
if(num <= 0) break;
if(!vis[i]){
if(num == 1) printf("%d
",i);
else printf("%d ",i);
num --;
vis[i] = true;
}
}
}
else{
for(int i = 0; i < k; ++ i){
printf("%d",res[i]);
if(i == k - 1) printf("
");
else printf(" ");
}
}
return 0;
}