Skip to content

[강신지-13주차 알고리즘 스터디] #28

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

Open
wants to merge 15 commits into
base: akstp1717/week13
Choose a base branch
from
1 change: 1 addition & 0 deletions week1/.gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions week10/.gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

46 changes: 46 additions & 0 deletions week10/BOJ11403.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import java.io.*;
import java.util.*;

public class BOJ11403 {

public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());

int[][] graph = new int[N][N];

for (int i=0; i<N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j=0; j<N; j++) {
graph[i][j] = Integer.parseInt(st.nextToken());
}
}

int[][] result = new int[N][N];

for (int i=0; i<N; i++) {
boolean[] visited = new boolean[N];
Queue<Integer> q = new LinkedList<>();
q.add(i);

while(!q.isEmpty()) {
int current = q.poll();

for (int j=0; j<N; j++) {
if (visited[j] || graph[current][j] == 0) continue;

visited[j] = true;
q.add(j);
result[i][j] = 1;
}
}
}

for (int i=0; i<N; i++) {
for (int j=0; j<N; j++) {
System.out.print(result[i][j]+" ");
}
System.out.println();
}
}
}
79 changes: 79 additions & 0 deletions week10/BOJ1197.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import java.io.*;
import java.util.*;

public class BOJ1197 {
static int[] parent;

static class Edge implements Comparable<Edge> {
int u, v, w;

Edge(int u, int v, int w) {
this.u = u;
this.v = v;
this.w = w;
}

@Override
public int compareTo(Edge other) {
return this.w - other.w;
}
}

public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());

int V = Integer.parseInt(st.nextToken());
int E = Integer.parseInt(st.nextToken());

// 간선 정보를 저장할 리스트
List<Edge> edges = new ArrayList<>();
for (int i = 0; i < E; i++) {
st = new StringTokenizer(br.readLine());
int u = Integer.parseInt(st.nextToken());
int v = Integer.parseInt(st.nextToken());
int w = Integer.parseInt(st.nextToken());
edges.add(new Edge(u, v, w));
}

// 간선을 가중치 기준으로 오름차순 정렬
Collections.sort(edges);

// 각 정점의 부모를 자기 자신으로 초기화
parent = new int[V + 1];
for (int i = 1; i <= V; i++) {
parent[i] = i;
}

long result = 0; // MST의 총 가중치를 저장할 변수
int count = 0; // 선택된 간선의 수

for (Edge edge : edges) {
// 두 정점을 연결했을 때 사이클이 생기지 않으면 union 수행
if (union(edge.u, edge.v)) {
result += edge.w;
count++;
// 간선 V-1개 선택되면 MST 완성됨
if (count == V - 1) break;
}
}

System.out.println(result);
}

public static int find(int a) {
if (parent[a] != a) {
parent[a] = find(parent[a]);
}
return parent[a];
}

// 두 정점을 합칠 수 있으면 true, 사이클 형성 시 false 반환
public static boolean union(int a, int b) {
int rootA = find(a);
int rootB = find(b);
if (rootA == rootB) return false;
parent[rootB] = rootA;
return true;
}
}
83 changes: 83 additions & 0 deletions week10/BOJ1238.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import java.io.*;
import java.util.*;

public class BOJ1238 {
static class Edge implements Comparable<Edge> {
int to, weight;
Edge(int to, int weight) {
this.to = to;
this.weight = weight;
}
public int compareTo(Edge o) {
return this.weight - o.weight;
}
}

static int INF = Integer.MAX_VALUE;

public static int[] dijkstra(int start, ArrayList<Edge>[] graph, int n) {
int[] dist = new int[n + 1];
Arrays.fill(dist, INF);
dist[start] = 0;
PriorityQueue<Edge> pq = new PriorityQueue<>();
pq.add(new Edge(start, 0));

while (!pq.isEmpty()) {
Edge current = pq.poll();
int cur = current.to;
int curDist = current.weight;

// 현재 저장된 거리보다 큰 경우 스킵
if (curDist > dist[cur]) continue;

for (Edge edge : graph[cur]) {
int next = edge.to;
int nextDist = curDist + edge.weight;
if (nextDist < dist[next]) {
dist[next] = nextDist;
pq.add(new Edge(next, nextDist));
}
}
}
return dist;
}

public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken()); // 정점 개수
int M = Integer.parseInt(st.nextToken()); // 간선 개수
int X = Integer.parseInt(st.nextToken()); // 파티가 열리는 정점

// 원래 그래프와 간선을 뒤집은 역방향 그래프 생성
ArrayList<Edge>[] graph = new ArrayList[N + 1];
ArrayList<Edge>[] revGraph = new ArrayList[N + 1];
for (int i = 1; i <= N; i++) {
graph[i] = new ArrayList<>();
revGraph[i] = new ArrayList<>();
}

for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int from = Integer.parseInt(st.nextToken());
int to = Integer.parseInt(st.nextToken());
int weight = Integer.parseInt(st.nextToken());
graph[from].add(new Edge(to, weight));
// 역방향 그래프: 도착지를 from으로, from을 to로 저장
revGraph[to].add(new Edge(from, weight));
}

// X에서 각 정점까지 최단 경로
int[] distFromX = dijkstra(X, graph, N);
// 각 정점에서 x로 가는 최단 경로
int[] distToX = dijkstra(X, revGraph, N);

// 모든 정점에 대해 왕복 시간의 최댓값 계산
int maxTime = 0;
for (int i = 1; i <= N; i++) {
maxTime = Math.max(maxTime, distFromX[i] + distToX[i]);
}

System.out.println(maxTime);
}
}
88 changes: 88 additions & 0 deletions week10/BOJ14940.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import java.io.*;
import java.util.*;

public class BOJ14940 {
static int N, M, startX, startY;
static boolean[][] visited;
static int[][] map;
static int[][] result;

static int[] dx = {-1, 1, 0, 0};
static int[] dy = {0, 0, -1, 1};

public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
StringBuilder sb = new StringBuilder();

N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());

map = new int[N][M];
visited = new boolean[N][M];
result = new int[N][M];

for (int i=0; i<N; i++) {
st = new StringTokenizer(br.readLine());
for (int j=0; j<M; j++) {
map[i][j] = Integer.parseInt(st.nextToken());

// 2이면 start 좌표 저장
if (map[i][j] == 2) {
startX = i;
startY = j;
}

// 0이면 미리 방문 처리
if (map[i][j] == 0) visited[i][j] = true;
}
}

bfs(); // bfs로 거리 구하기

for (int i=0; i<N; i++) { // 원래 갈 수 있는 땅인 부분 중 도달할 수 없는 위치는 -1
for (int j=0; j<M; j++) {
if (map[i][j] == 1 && result[i][j]==0) {
result[i][j] = -1;
}
}
}

for (int i=0; i<N; i++) { // 출력
for (int j=0; j<M; j++) {
sb.append(result[i][j]).append(' ');
}
sb.append('\n');
}
System.out.println(sb);
}


static void bfs() {
Queue<int[]> q = new LinkedList<>();
q.offer(new int[] {startX, startY});
result[startX][startY] = 0;
visited[startX][startY] = true;

while(!q.isEmpty()) {
int[] current = q.poll();
for (int i=0; i<4; i++) {
int x = current[0]+dx[i];
int y = current[1]+dy[i];

// 범위 벗어나거나, 이미 방문했을 경우
if (!isOk(x, y) || visited[x][y]) continue;

visited[x][y] = true;
result[x][y] = result[current[0]][current[1]]+1;
q.offer(new int[] {x, y});
}
}
}


static boolean isOk(int x, int y) { // 범위 체크
if (x<0 || y<0 || x>=N || y >=M) return false;
return true;
}
}
53 changes: 53 additions & 0 deletions week10/BOJ16928.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import java.io.*;
import java.util.*;

public class BOJ16928 {
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());

int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());

int[] move = new int[101];
boolean[] visited = new boolean[101];

for (int i=0; i<N+M; i++) {
st = new StringTokenizer(br.readLine());

int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());

move[x] = y;
}

Queue<int[]> q = new LinkedList<>();
q.add(new int[] {1, 0});
visited[1] = true;

while (!q.isEmpty()) {
int[] current = q.poll();

if (current[0] == 100) { // 100까지 도달!
System.out.println(current[1]);
return;
}

for (int i=1; i<7; i++) {
int next = current[0] + i;

// 100 넘어가거나 방문한 곳이면 continue
if (next > 100 || visited[next]) continue;

if (move[next] != 0) { // 뱀, 사다리 중 하나이면
next = move[next]; // 해당 값으로 이동
}

q.add(new int[] {next, current[1]+1});
visited[next] = true;
}
}

System.out.println();
}
}
1 change: 1 addition & 0 deletions week11/.gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

28 changes: 28 additions & 0 deletions week11/BOJ11727.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import java.io.*;

public class BOJ11727 {
static int N;
static int[] dp;

public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

N = Integer.parseInt(br.readLine());

if (N == 1) {
System.out.println(1);
return;
}

dp = new int[N+1];
dp[1] = 1;
dp[2] = 3;

// 마지막 2*2 타일을 채우는 경우(2가지) + 2*1 타일을 채우는 경우
for (int i=3; i<=N; i++) {
dp[i] = (dp[i-2]*2+dp[i-1]) % 10007;
}

System.out.println(dp[N]);
}
}
Loading