SDS ( -> PS)
[7일차] 그래프2 B - 1753: 최단경로
왕방토
2022. 1. 11. 16:21
728x90
골드 Ⅴ
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define INF 987654321
using namespace std;
struct NodeInfo {
int node;
int weightOrshdis;
};
struct compare {
bool operator()(const NodeInfo& NodeInfo1, const NodeInfo& NodeInfo2) {
return NodeInfo1.weightOrshdis > NodeInfo2.weightOrshdis;
}
};
//그래프 연결관계 저장 -> nodeNum, weight
vector<NodeInfo> adjList[20001];//노드 넘버와 그 노드까지 가는데 드는 weight 저장 필요
//nodeNum, shdis -> shdis로 정렬할거라 둘다 넣어줘야함
priority_queue<NodeInfo, vector<NodeInfo>, compare> toStart;
//이색 왜필요하지 일단 필요할거같으니까 써놓고 필요없으면 지우기
int shdis[20001];//각 노드들의 최단 거리! 저장 최단 경로가 아니라
bool visit[20001] = { 0, };//false로 초기화
int V, E, K;
int main() {
scanf("%d%d%d", &V, &E, &K);
//shdis inf로 초기화
for (int i = 1; i <= V; i++) {
if (i == K) shdis[i] = 0;
else shdis[i] = INF;
}
toStart.push({ K, 0 });//시작점 넣어주기
//연결 정보 받아주기
int u, v, w;
while (E--) {
scanf("%d%d%d", &u, &v, &w);
//노드 u와 연결된 얘들 i 중에
bool isDup = false;
for (int i = 0; i < adjList[u].size(); i++) {
int connectedNode = adjList[u][i].node;
int oldweight = adjList[u][i].weightOrshdis;
//연결된 노드에 이미 v가 있다면 w 업데이트
if (connectedNode == v) {
printf("중복이네 %d -> %d\n", oldweight, w);
adjList[u][i].weightOrshdis = min(oldweight, w);
printf("%d됨\n", adjList[u][i].weightOrshdis);
isDup = true;
}
}
//중복 안됐다면 업데이트
if (!isDup) adjList[u].push_back({ v, w });
}
//인접리스트 출력
for (int i = 1; i <= V; i++) {
printf("노드 %d: \n", i);
for (int j = 0; j < adjList[i].size(); j++) {
printf("(to %d -> weight: %d)\n", adjList[i][j].node, adjList[i][j].weightOrshdis);
}
}//졸라 잘 들어감 출력이 이해하기 쉽네 굳굳
//다익스트라 ㄱㄱ
while (!toStart.empty()) {
int startNode = toStart.top().node;
toStart.pop();
visit[startNode] = true;
printf("노드 %d에서 시작!\n", startNode);
//뽑은 startNode와 연결된 node 업데이트 해주기
for (int i = 0; i < adjList[startNode].size(); i++) {
int connectedNode = adjList[startNode][i].node;
int weight = adjList[startNode][i].weightOrshdis;
printf("to -> %d : weight : %d\n", connectedNode, weight);
//방문한 노드면 스킵
if (visit[connectedNode] == true) continue;
//연결된 node의 현재 shdis보다 startNode dis + weight가 더 작다면 update
if (shdis[connectedNode] > shdis[startNode] + weight) {
//shdis 업데이트
shdis[connectedNode] = shdis[startNode] + weight;
//tostart에 넣어주기 (to start에 이미 들어간 경우는 중복으로 들어가지만)
//(shdis가 더 작게 들어가므로 update해주는 효과를 냄)
//-> 더 큰 값으로 있던 건 무시됨
toStart.push({ connectedNode, shdis[connectedNode] });
}
}
}
for (int i = 1; i <= V; i++) {
if (shdis[i] == INF) printf("INF\n");
else printf("%d\n", shdis[i]);
}
}
다익스트라 + 다중간선이 있을 경우 더 작은값으로 치환
인 줄 알았는데 왜 강사님 코드 보니까 치환 안하지
머지
머임?
그리고... toStart 업데이트 안해주는거 내가 생각한게 맞는지 모르겠음 진짜 확인해야될거같음