임의의 한 정점으로부터 모든 정점까지의 거리를 계산하는 알고리즘
임의의 한 점으로부터 근처 정점 간 거리를 계산한 뒤, 아직 방문 전인 정점들 중에서 거리가 가장 가까운 정점을 차례대로 방문해 최소거리를 계산하게 됨
시간복잡도는 O(V 2 +E )
만약, 간선의 개수 E 가 그렇게 크지 않다면, heap
을 사용해 시간복잡도를 O(E log E ) 로 줄여 사용할 수 있음
간선의 크기가 거의 V 2 에 근접하다면, heap
이 아닌 일반적인 구현 방법을 사용하는 것이 더 효율적일 수 있음
#include < bits/stdc++.h>
using namespace std ;
int main (void )
{
ios::sync_with_stdio (false );
cin.tie (NULL );
int v, e;
cin>>v>>e;
int start;
cin>>start;
// u, {cost, v};
vector<vector<pair<int , int >>> adj_list (v+1 );
while (e--) {
int u, v, w;
cin>>u>>v>>w;
adj_list[u].push_back ({w,v});
}
// cost, v
vector<int > d (v+1 , 1e9 );
d[start]=0 ;
priority_queue<pair<int , int >,
vector<pair<int , int >>,
greater<pair<int , int >>> pq;
pq.push ({d[start],start});
while (!pq.empty ()) {
auto cur = pq.top ();
pq.pop ();
int dist = cur.first ;
int vtx = cur.second ;
// 예전 정보는 무시
if (d[vtx]!=dist) {
continue ;
}
for (auto nxt : adj_list[vtx]) {
int cost = nxt.first ;
int nxt_vtx = nxt.second ;
if (d[nxt_vtx]>dist+cost) {
d[nxt_vtx]=dist+cost;
pq.push ({d[nxt_vtx],nxt_vtx});
}
}
}
for (int i = 1 ; i<=v; ++i) {
if (d[i]==1e9 ) {
cout << " INF" ;
}
else {
cout << d[i];
}
cout << ' \n ' ;
}
return 0 ;
}
// https://www.acmicpc.net/problem/1916
#include < bits/stdc++.h>
using namespace std ;
int main (void )
{
ios::sync_with_stdio (false );
cin.tie (NULL );
int v, e;
cin>>v>>e;
// u, {cost, v};
vector<vector<pair<int , int >>> adj_list (v+1 );
while (e--) {
int u, v, w;
cin>>u>>v>>w;
adj_list[u].push_back ({w,v});
}
int st, en;
cin>>st>>en;
// cost, v
vector<int > d (v+1 , 1e9 );
d[st]=0 ;
priority_queue<pair<int , int >,
vector<pair<int , int >>,
greater<pair<int , int >>> pq;
pq.push ({d[st],st});
while (!pq.empty ()) {
auto cur = pq.top ();
pq.pop ();
int dist = cur.first ;
int vtx = cur.second ;
if (d[vtx]!=dist) {
continue ;
}
for (auto nxt : adj_list[vtx]) {
int cost = nxt.first ;
int nxt_vtx = nxt.second ;
if (d[nxt_vtx]>dist+cost) {
d[nxt_vtx]=dist+cost;
pq.push ({d[nxt_vtx],nxt_vtx});
}
}
}
cout << d[en] << ' \n ' ;
return 0 ;
}
#include < bits/stdc++.h>
using namespace std ;
int main (void )
{
ios::sync_with_stdio (false );
cin.tie (NULL );
int v, e;
cin>>v>>e;
// u, {cost, v};
vector<vector<pair<int , int >>> adj_list (v+1 );
while (e--) {
int u, v, w;
cin>>u>>v>>w;
adj_list[u].push_back ({w,v});
}
int st, en;
cin>>st>>en;
// cost, v
vector<int > d (v+1 , 1e9 );
d[st]=0 ;
vector<int > p (v+1 );
priority_queue<pair<int , int >,
vector<pair<int , int >>,
greater<pair<int , int >>> pq;
pq.push ({d[st],st});
while (!pq.empty ()) {
auto cur = pq.top ();
pq.pop ();
int dist = cur.first ;
int vtx = cur.second ;
// 예전 정보는 무시
if (d[vtx]!=dist) {
continue ;
}
for (auto nxt : adj_list[vtx]) {
int cost = nxt.first ;
int nxt_vtx = nxt.second ;
if (d[nxt_vtx]>dist+cost) {
d[nxt_vtx]=dist+cost;
pq.push ({d[nxt_vtx],nxt_vtx});
p[nxt_vtx]=vtx;
}
}
}
cout << d[en] << ' \n ' ;
stack<int > s;
int r = en;
s.push (r);
while (st!=p[r]) {
r=p[r];
s.push (r);
}
s.push (st);
cout << s.size () << ' \n ' ;
while (!s.empty ()) {
cout << s.top () << ' ' ;
s.pop ();
}
return 0 ;
}
벨만 포드(Bellman-Ford) 알고리즘 - WIP
정점 간 거리가 음수가 포함되었을 때 처리하는 방법