백준문제풀이
백준 문제 1753번 최단경로 문제풀이 c++
노가다 김씨
2022. 3. 22. 14:25
https://www.acmicpc.net/problem/1753
1753번: 최단경로
첫째 줄에 정점의 개수 V와 간선의 개수 E가 주어진다. (1 ≤ V ≤ 20,000, 1 ≤ E ≤ 300,000) 모든 정점에는 1부터 V까지 번호가 매겨져 있다고 가정한다. 둘째 줄에는 시작 정점의 번호 K(1 ≤ K ≤ V)가
www.acmicpc.net
문제해석
다익스트라 문제이다.
그런데 정점의 개수가 20000개라서 n^2 다익스트라로 구현하면 시간초과가 난다.
그래서 현재 상태에서 가장 가까운 정점을 구하는것을 우선순위큐로 구현하면 시간 초과를 피할수있다.
다익스트라를 실행하고 처음 d배열을 세팅할때 그리고 지금까지의 거리보다 거쳐서 가는 길이 더 최단인경우에 우선순위 큐에 그 정보를 푸쉬해주면된다.
코드
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#define INF 999999999
using namespace std;
int getsmall();
void dijk(int start);
bool visited[20001];
int d[20001];
priority_queue < pair<int,int> > pq;
vector <pair<int,int>> vec[20001];
int main(){
cout.tie(NULL);
cin.tie(NULL);
ios_base::sync_with_stdio(false);
int V,E,K,u,v,w;
cin>>V>>E>>K;
for(int i=0; i<E; i++)
{
cin>>u>>v>>w;
vec[u].push_back({w,v});
}
dijk(K);
for(int i=1; i<=V; i++)
{
if(K==i)
{
cout<<"0\n";
}
else
{
if(d[i]==INF)
{
cout<<"INF\n";
}
else
{
cout<<d[i]<<"\n";
}
}
}
}
int getsmall(){
int index=0;
while(!pq.empty())
{
index=pq.top().second;
pq.pop();
if(visited[index]==0)
{
return index;
}
}
return index;
}
void dijk(int start){
int v,w;
for(int i=0; i<20001; i++)
{
if(start==i)
{
d[i]=0;
}
else
{
d[i]=INF;
}
}
for(int i=0; i<vec[start].size(); i++)
{
w=vec[start][i].first;
v=vec[start][i].second;
d[v]=min(d[v],w);
}
visited[start]=1;
for(int i=0; i<20001; i++)
{
pq.push({-d[i],i});
}
for(int i=0; i<20001; i++)
{
int cur=getsmall();
visited[cur]=1;
for(int j=0; j<vec[cur].size(); j++)
{
w=vec[cur][j].first;
v=vec[cur][j].second;
if(visited[v]==0&&d[cur]+w<d[v])
{
d[v]=d[cur]+w;
pq.push({-d[v],v});
}
}
}
}