중간에 시작 노드를 지나갈 수 없으므로 (처음을 제외한) 시작 노드 이후의 경로는 탐색하지 않도록 한다.
경로 출력은 큐에 넣는 작업을 할때마다 그 때의 이전 노드를 따로 저장 (즉, 어디서부터 왔는 가를 저장)하여 마지막엔 시작 노드로부터 그 역순으로 따라올라가면 경로를 얻을 수 있다.
#include <bits/stdc++.h>
using namespace std;
#define INF 987654321
typedef long long lld;
typedef pair<int,int> ii;
void solve(vector<ii> adj[], int n, int s){
vector<int> cost(n, 0);
priority_queue<ii> q;
q.push({0, s});
cost[s] = 0;
bool looped = false;
vector<int> trace(n, 0);
while(!q.empty()){
int pos = q.top().second;
int dist = q.top().first;
q.pop();
if(pos == s){
if(looped) continue;
looped = true;
}
for(int i=0; i<adj[pos].size(); ++i){
ii& next = adj[pos][i];
if(dist + next.second < cost[next.first]) continue;
q.push({dist+next.second, next.first});
cost[next.first] = dist+next.second;
trace[next.first] = pos;
}
}
printf("%d\n", cost[s]);
int pos = trace[s];
vector<int> ret(1, 0);
while(pos != s){
ret.push_back(pos);
pos = trace[pos];
}
if(ret.size() > 1) printf("1 ");
for(int i=(int)ret.size()-1; i>=0; --i)
printf("%d ", ret[i]+1);
}
int main(){
int n, m;
scanf("%d %d", &n, &m);
vector<ii> adj[n];
while(m--){
int v, w, x;
scanf("%d %d %d", &v, &w, &x);
adj[v-1].push_back({w-1, x});
}
solve(adj, n, 0);
return 0;
}
댓글 없음:
댓글 쓰기