Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 어셈블리어
- 멀티플렉싱
- 터미널제어
- 서버 프로그래밍
- 가상상속
- lseek
- canonical
- termcap
- termios
- UNIX
- nonblock
- cursor
- pipe buffer
- 터미널 제어
- opcode
- Assembly
- multiplexing
- 터미널 커서
- MAN
- getch
- 가상 상속
- kevent
- 레지스터
- 커서 제어
- 클래스 상속
- virtual 상속
- 명령어
- 프롬프트
- kqueue
- IPC
Archives
- Today
- Total
오늘도 밤이야
[BOJ] 1865번: 웜홀 (C++) 본문
0. 문제
https://www.acmicpc.net/problem/1865
도로를 양방향 양수 가중치 간선으로, 웜홀을 단방향 음수 가중치 간선으로 치환하면, 그래프에서 음수 사이클이 존재 여부를 확인하는 문제이다.
1. 아이디어
최단 거리 알고리즘 중 음수 사이클 존재 여부를 판단하기 쉬운 알고리즘으로 Floyd-Warshall이 먼저 떠올랐다. All-Pair Shortest Path 알고리즘이기 때문에 시간복잡도 면에서 그렇게 효율적이진 않을 수 있으나, 정점의 최대 개수 V가 500개이기 때문에 O(V^3) 알고리즘인 Floyd-Warshall도 시간 안에 동작하고, 구현이 쉽다는 장점이 있다.
2. 풀이
bool check_neg_cycle(std::vector<std::vector<int>> &adjmat, int n)
{
std::vector<std::vector<int>> a(adjmat);
for (int k = 1; k <= n; ++k)
{
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= n; ++j)
{
if (a[i][j] > a[i][k] + a[k][j])
{
a[i][j] = a[i][k] + a[k][j];
}
}
}
}
for (int i = 1; i <= n; ++i)
{
if (a[i][i] < 0)
{
return true;
}
}
return false;
}
Floyd-Warshall 알고리즘 수행 후, 특정 정점에서부터 해당 정점으로 돌아오는 거리가 음수일 경우 음수 사이클이 존재한다. 즉 문제에서 요구하는 시간이 줄어들고 출발 지점으로 돌아오는 방법이 존재하는 것이다.
아래는 전체 솔루션 코드이다.
#include <iostream>
#include <vector>
#define INF 1 << 29
struct edge
{
int u;
int v;
int w;
};
bool check_neg_cycle(std::vector<std::vector<int>> &adjmat, int n)
{
std::vector<std::vector<int>> a(adjmat);
for (int k = 1; k <= n; ++k)
{
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= n; ++j)
{
if (a[i][j] > a[i][k] + a[k][j])
{
a[i][j] = a[i][k] + a[k][j];
}
}
}
}
for (int i = 1; i <= n; ++i)
{
if (a[i][i] < 0)
{
return true;
}
}
return false;
}
int main()
{
int tc;
std::cin >> tc;
int n, m, w;
int s, e, t;
while (tc--)
{
std::cin >> n >> m >> w;
std::vector<std::vector<int>> adjmat(501, std::vector<int>(501, INF));
for (int i = 0; i < m; ++i)
{
std::cin >> s >> e >> t;
if (adjmat[s][e] > t)
{
adjmat[s][e] = t;
}
if (adjmat[e][s] > t)
{
adjmat[e][s] = t;
}
}
for (int i = 0; i < w; ++i)
{
std::cin >> s >> e >> t;
if (adjmat[s][e] > -t)
{
adjmat[s][e] = -t;
}
}
for (int i = 1; i <= n; ++i)
{
if (adjmat[i][i] == INF)
{
adjmat[i][i] = 0;
}
}
std::cout << (check_neg_cycle(adjmat, n) ? "YES" : "NO") << '\n';
}
}
'PS > BOJ' 카테고리의 다른 글
[BOJ] 1918번: 후위 표기식 (C++) (0) | 2024.10.27 |
---|---|
[BOJ] 16283번: Farm (C++) (0) | 2024.10.27 |
[BOJ] 11399번: ATM (C++) (0) | 2024.08.24 |
Comments