Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[13_최단경로] 5월 28일 #12

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"utility": "cpp",
"queue": "cpp",
"deque": "cpp"
}
},
"C_Cpp.errorSquiggles": "disabled"
}
70 changes: 70 additions & 0 deletions 13_최단경로/1238.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include <iostream>
#include <vector>
#include <queue>
#include <limits>

#define pii pair<int, int>

using namespace std;

int numNodes, numEdges, target;
const int INFINITY = numeric_limits<int>::max();
vector<pii> adjList[2][1001];
vector<int> shortestDist[2];
int combinedDist[1001];

void readInput() {
int start, end, time;
cin >> numNodes >> numEdges >> target;
for (int i = 0; i < numEdges; ++i) {
cin >> start >> end >> time;
adjList[0][start].push_back(make_pair(time, end));
adjList[1][end].push_back(make_pair(time, start));
}
shortestDist[0].resize(numNodes + 1, INFINITY);
shortestDist[1].resize(numNodes + 1, INFINITY);
}

void dijkstra(int direction) {
shortestDist[direction][target] = 0;
priority_queue<pii, vector<pii>, greater<pii>> pq;
pq.push({0, target});

while (!pq.empty()) {
int currentCost = pq.top().first;
int currentNode = pq.top().second;
pq.pop();

if (currentCost > shortestDist[direction][currentNode]) continue;

for (auto &neighbor : adjList[direction][currentNode]) {
int nextNode = neighbor.second;
int nextCost = currentCost + neighbor.first;

if (nextCost < shortestDist[direction][nextNode]) {
shortestDist[direction][nextNode] = nextCost;
pq.push({nextCost, nextNode});
}
}
}
}

int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);

readInput();

dijkstra(1);
dijkstra(0);

int maxDistance = 0;
for (int i = 1; i <= numNodes; ++i) {
maxDistance = max(maxDistance, shortestDist[0][i] + shortestDist[1][i]);
}

cout << maxDistance;

return 0;
}
79 changes: 79 additions & 0 deletions 13_최단경로/15685.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#include <iostream>
#include <vector>

using namespace std;

const int SIZE = 100;

// 방향: 우(0), 상(1), 좌(2), 하(3)
int dy[4] = { 0, -1, 0, 1 };
int dx[4] = { 1, 0, -1, 0 };

// 1x1 정사각형 개수 계산 함수
int cntSquares(vector<vector<bool>>& plane) {
int ans = 0;
// 평면을 순회하면서 1x1 정사각형을 찾음
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
// (i, j), (i+1, j), (i, j+1), (i+1, j+1) 이 모두 true이면 정사각형이 됨
if (plane[i][j] && plane[i + 1][j] && plane[i][j + 1] && plane[i + 1][j + 1]) {
ans++;
}
}
}
return ans;
}

// 평면에 드래곤 커브를 그리는 함수
void drawDragonCurve(vector<vector<bool>>& plane, int x, int y, int d, int g) {
vector<int> direct; // 방향을 저장하는 벡터
// 초기 세대 드래곤 커브를 평면에 표시
plane[y][x] = plane[y + dy[d]][x + dx[d]] = true;
x += dx[d];
y += dy[d];
direct.push_back(d);

// g 세대까지 드래곤 커브 그리기
while (g--) {
int size_d = direct.size();
// 이전 세대의 방향을 기반으로 새로운 방향 계산
for (int j = size_d - 1; j >= 0; j--) {
int next_d = (direct[j] + 1) % 4; // 시계 방향으로 90도 회전
x += dx[next_d];
y += dy[next_d];
plane[y][x] = true; // 새로운 점을 평면에 표시
direct.push_back(next_d); // 새로운 방향을 벡터에 추가
}
}
}

/*
* 규칙:
* 0 세대: 0
* 1 세대: 0 1
* 2 세대: 0 1 2 1
* 3 세대: 0 1 2 1 2 3 2 1
* ...
* N 세대: concat((N-1세대), ((N-1세대 거꾸로) + 1)%4)
* 평면(좌측 상단이 (0, 0))에 드래곤 커브를 그린 후 정사각형의 개수를 계산
* 드래곤 커브는 평면 밖으로 나가지 않으므로 범위를 확인할 필요 없음
* 1. 0 세대의 드래곤 커브를 먼저 저장 (초기 조건)
* 2. 세대를 거듭하면서 드래곤 커브를 그림 (규칙을 파악하는 것이 중요)
* 3. 드래곤 커브가 그려진 평면 상의 정사각형의 개수 계산 (네 꼭짓점 확인)
*/

int main()
{
int n, x, y, d, g;
vector<vector<bool>> plane(SIZE + 1, vector<bool>(SIZE + 1, false)); // 평면
// 입력
cin >> n;
// 연산 & 출력
while (n--) { // n개의 드래곤 커브 그리기
cin >> x >> y >> d >> g;
drawDragonCurve(plane, x, y, d, g);
}
// 드래곤 커브가 그려진 평면에서 1x1 정사각형 개수를 출력
cout << cntSquares(plane) << '\n';
return 0;
}
53 changes: 53 additions & 0 deletions 13_최단경로/2458.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <iostream>
using namespace std;

const int INFINITY = 9999999;
const int MAX_SIZE = 502;
int numStudents, numComparisons;
int heightMap[MAX_SIZE][MAX_SIZE];

void floydWarshall() {
for (int k = 1; k <= numStudents; k++) {
for (int i = 1; i <= numStudents; i++) {
for (int j = 1; j <= numStudents; j++) {
if (heightMap[i][j] > heightMap[i][k] + heightMap[k][j]) {
heightMap[i][j] = heightMap[i][k] + heightMap[k][j];
}
}
}
}
}

int main() {
cin >> numStudents >> numComparisons;

for (int i = 1; i <= numStudents; i++) {
for (int j = 1; j <= numStudents; j++) {
heightMap[i][j] = INFINITY;
}
}

for (int i = 0; i < numComparisons; i++) {
int taller, shorter;
cin >> taller >> shorter;
heightMap[taller][shorter] = 1;
}

floydWarshall();

int count = 0;
for (int i = 1; i <= numStudents; i++) {
int knownRelations = 0;
for (int j = 1; j <= numStudents; j++) {
if (heightMap[i][j] != INFINITY || heightMap[j][i] != INFINITY) {
knownRelations++;
}
}
if (knownRelations == numStudents - 1) {
count++;
}
}
cout << count << endl;

return 0;
}