| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 |
Tags
- 최소 공통 조상
- PROJECT
- Spin Lock
- trie
- JavaScript
- 벨만-포드
- Behavior Design Pattern
- 게임 서버 아키텍처
- Strongly Connected Component
- 자바스크립트
- Express.js
- SCC
- 트라이
- 비트필드를 이용한 dp
- DP
- ccw 알고리즘
- localstorage
- 이분 탐색
- reference counting
- Lock-free Stack
- 강한 연결 요소
- 2-SAT
- 그래프 탐색
- R 그래프
- Binary Lifting
- Github
- Delete
- 비트마스킹
- map
- Prisma
Archives
- Today
- Total
dh_0e
[PS] 임계경로 / C++ (백준 1948번) 본문
DAG(방향 비순환 그래프)를 항상 만족하는 상황에서 최장거리를 구하는 문제.
풀이 과정
- 처음엔 다익스트라 스타일로 최장 거리를 구하는 스타일로 풀어서 AC를 받았지만, 분명 $O(MlogN)$인데 시간이 너무 오래 걸렸다.
- 다익스트라 느낌으로 prique를 써서 역방향 탐색하며 역추적을 위해 _next 벡터에 다음 node를 저장하면서 진행했는데, 생각해보니 어짜피 모든 간선을 탐색해야 하는데 굳이 prique를 써서 사용해야 하나 싶었다.
- 이후, 위상정렬을 이용해 dp로 풀었더니 $O(M+N)$으로 시간을 많이 단축시킬 수 있었다.
다익스트라 스타일 ($O(MlogN)$)
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
struct data {
int dep;
int cost;
bool operator<(const data p)const {
return p.cost > cost;
}
};
vector<struct data> vec[10'001];
vector<int> _next[10'001];
int _cost[10'001];
bool vi[10'001];
int dap = 0;
void dfs(int p)
{
vi[p] = 1;
int size = _next[p].size();
for (int i = 0; i < size; i++) {
int tar = _next[p][i];
dap++;
if (!vi[tar])dfs(tar);
}
}
int main()
{
int n, m, st, en;
scanf("%d %d", &n, &m);
for (int i = 0; i < m; i++) {
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
vec[v].push_back({u, w});
}
scanf("%d %d", &st, &en);
priority_queue<struct data> que;
que.push({ en, 0 });
while (!que.empty()) {
struct data cur = que.top();
que.pop();
int size = vec[cur.dep].size();
for (int i = 0; i < size; i++) {
struct data target = vec[cur.dep][i];
if (_cost[target.dep] == 0) {
_cost[target.dep] = cur.cost + target.cost;
_next[target.dep].push_back(cur.dep);
que.push({ target.dep, _cost[target.dep] });
}
else if(_cost[target.dep] < cur.cost + target.cost) {
_cost[target.dep] = cur.cost + target.cost;
_next[target.dep].clear();
_next[target.dep].push_back(cur.dep);
que.push({ target.dep, _cost[target.dep] });
}
else if (_cost[target.dep] == cur.cost + target.cost) {
_next[target.dep].push_back(cur.dep);
}
}
}
printf("%d\n", _cost[st]);
dfs(st);
printf("%d\n", dap);
return 0;
}
위상 정렬(DP) ($O(N+M)$)
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
struct data {
int node;
int cost;
};
vector<struct data> fwd[10'001], opp[10'001];
int lev[10'001], _cost[10'001];
bool vi[10'001];
int dap = 0;
void dfs(int p)
{
for (auto& edge : opp[p]) {
if (_cost[p] == _cost[edge.node] + edge.cost) {
dap++;
if (!vi[edge.node]) {
vi[edge.node] = 1;
dfs(edge.node);
}
}
}
return;
}
int main()
{
int n, m, st, en;
scanf("%d %d", &n, &m);
for (int i = 0; i < m; i++) {
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
fwd[u].push_back({ v, w });
opp[v].push_back({u, w});
lev[v]++;
}
scanf("%d %d", &st, &en);
queue<int> que;
que.push(st);
while (!que.empty()) {
int cur = que.front();
que.pop();
for (auto& edge : fwd[cur]) {
if (_cost[edge.node] == 0)_cost[edge.node] = _cost[cur] + edge.cost;
else if (_cost[edge.node] < _cost[cur] + edge.cost) {
_cost[edge.node] = _cost[cur] + edge.cost;
}
lev[edge.node]--;
if (lev[edge.node] == 0)que.push(edge.node);
}
}
printf("%d\n", _cost[en]);
dfs(en);
printf("%d\n", dap);
return 0;
}'Problem Solving > Baekjoon' 카테고리의 다른 글
| [PS] 오아시스 재결합 / C++ (백준 3015번) (0) | 2026.01.28 |
|---|---|
| [PS] 전설 / C++ (백준 19585번) (0) | 2026.01.22 |
| [PS] 벽 부수고 이동하기 4 / C++ (백준 16946번) (0) | 2026.01.20 |
| [PS] 전깃줄-2 / C++ (백준 2568번) (0) | 2026.01.15 |
| [PS] 아기 상어 / C++ (백준 16236번) (0) | 2026.01.05 |
