코딩캠프/BOJ
[5719] 거의 최단경로
by 코곰_
2024. 2. 23.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define MAX_N 500
#define MAX_M 10000
#define MAX_VALUE 500500
using namespace std;
struct Node{
int dest; int cost;
Node(int dest, int cost) : dest(dest), cost(cost){
}
bool operator<(const Node& a)const{
return cost > a.cost;
}
};
int N, M, S, D;
vector<Node> adjList[MAX_N+5];
vector<int> delList[MAX_N+5];
int dist[MAX_N+5];
bool visited[MAX_N+5];
void dijkstra(int start){
priority_queue<Node> PQ;
dist[start] = 0;
PQ.push(Node(start, 0));
while(!PQ.empty()){
Node now = PQ.top();
PQ.pop();
if(dist[now.dest] < now.cost) continue;
for(Node next: adjList[now.dest]){
if(next.cost == -1) continue;
if(dist[next.dest] > next.cost + now.cost){
dist[next.dest] = next.cost + now.cost;
PQ.push(Node(next.dest, dist[next.dest]));
delList[next.dest].clear();
delList[next.dest].push_back(now.dest);
}
else if(dist[next.dest] == next.cost + now.cost){
delList[next.dest].push_back(now.dest);
}
}
}
}
void del_bfs(int start){
queue<int> Q;
Q.push(start);
while(!Q.empty()){
int now = Q.front();
Q.pop();
if(visited[now] != 0) continue;
visited[now] = 1;
for(int i=0; i<delList[now].size(); i++){
int next = delList[now][i];
for(int j=0; j<adjList[next].size(); j++){
if(adjList[next][j].dest == now){
adjList[next][j].cost = -1;
}
}
Q.push(next);
}
}
}
int main(){
while(1){
scanf("%d %d", &N, &M);
if(N==0 && M==0) break;
scanf("%d %d", &S, &D);
for(int i=0; i<N+1; i++){
adjList[i].clear();
delList[i].clear();
dist[i] = MAX_VALUE;
visited[i] = 0;
}
for(int i=0; i<M; i++){
int U, V, P;
scanf("%d %d %d", &U, &V, &P);
adjList[U].push_back(Node(V, P));
}
dijkstra(S);
del_bfs(D);
for(int i=0; i<N+1; i++){
dist[i] = MAX_VALUE;
}
dijkstra(S);
if(dist[D] == MAX_VALUE){
printf("-1\n");
}
else{
printf("%d\n", dist[D]);
}
}
}