728x90
728x90
00 ๋ฌธ์
01 ํธ๋ฆฌ์ ์ง๋ฆ?
- ํธ๋ฆฌ๋ ์ฌ์ดํด์ด ์๋ ๋ฌด๋ฐฉํฅ ๊ทธ๋ํ์ด๋ฉฐ, ์ด๋ค ๋ ๋ ธ๋๋ฅผ ์ ํํด๋ ๋ ์ฌ์ด์ ๊ฒฝ๋ก๊ฐ ํญ์ ํ๋๋ง ์กด์ฌํ๋ค.
- ํธ๋ฆฌ์์ ์ด๋ค ๋ ๋ ธ๋๋ฅผ ์ ํํด์ ์์ชฝ์ผ๋ก ๋น๊ธฐ๋ฉด, ๊ฐ์ฅ ๊ธธ๊ฒ ๋์ด๋๋ ๊ฒฝ์ฐ๊ฐ ์๋ค.
- ์ด๋ด ๋ ํธ๋ฆฌ์ ๋ชจ๋ ๋ ธ๋๋ค์ ์ด ๋ ๋ ธ๋๋ฅผ ์ง๋ฆ์ ๋์ ์ผ๋ก ํ๋ ์ ์์ ๋ค์ด๊ฐ๊ฒ ๋๋ค.
- ์ด๋ฐ ๋ ๋ ธ๋ ์ฌ์ด์ ๊ฒฝ๋ก์ ๊ธธ์ด๋ฅผ ํธ๋ฆฌ์ ์ง๋ฆ์ด๋ผ๊ณ ํ๋ค.
- ์ ํํ๋ ํธ๋ฆฌ์ ์กด์ฌํ๋ ๋ชจ๋ ๊ฒฝ๋ก๋ค ์ค ๊ฐ์ฅ ๊ธด ๊ฒฝ๋ก์ ๊ธธ์ด๋ฅผ ๋งํ๋ค.
- ๊ฐ์ฅ ๋จผ ๋ ์ ์ ์ฌ์ด์ ๊ฑฐ๋ฆฌ or ๊ฐ์ฅ ๋จผ ๋ ์ ์ ์ ์ฐ๊ฒฐํ๋ ๊ฒฝ๋ก๋ฅผ ์๋ฏธํ๋ค.
02 ํธ๋ฆฌ์ ์ง๋ฆ์ ๊ตฌํ๋ ๋ฐฉ๋ฒ
- ํธ๋ฆฌ์์ ์์์ ์ ์ x๋ฅผ ์ก๋๋ค.
- ์ ์ x์์ ๊ฐ์ฅ ๊น์ ๋ ธ๋ ์ค ๊ฐ์ค์น๊ฐ ๊ฐ์ฅ ํฐ ์ ์ y๋ฅผ ์ฐพ๋๋ค. -> DFS ์ด์ฉ
- ์ ์ y์์ ๊ฐ์ฅ ๊น์ ๋ ธ๋ ์ค ๊ฐ์ค์น๊ฐ ๊ฐ์ฅ ํฐ ์ ์ z๋ฅผ ์ฐพ๋๋ค. -> DFS ์ด์ฉ
- ํธ๋ฆฌ์ ์ง๋ฆ์ ์ ์ y์ ์ ์ z๋ฅผ ์ฐ๊ฒฐํ๋ ๊ฒฝ๋ก๋ค. (y-z)
03 DFS๋ฅผ ๋๋ฒ ์ด์ฉํ์ฌ ํธ๋ฆฌ์ ์ง๋ฆ์ ๊ตฌํ๋ค.
- ๊ฐ์ค์น๊ฐ ๊ฐ์ฅ ํฐ ์ ์ ์ ์ฐพ๊ธฐ ์ํด์ push ํ ๋ ๋ง๋ค sPos, sMax์ ํ์ฌ ๋ ธ๋์ ๊ฑฐ๋ฆฌ ๊ฐ์ ์ ์ฅํ๋ค.
- ์ฐ์ฐ์ด ์ ๋ถ ๋๋ ํ sMax ๋ฐฐ์ด ์ค ๊ฐ์ฅ ํฐ ๊ฐ์ ์ฐพ์ sMax_์ ์ ์ฅํ ํ, ๊ฐ์ ์ธ๋ฑ์ค์ ํด๋นํ๋ sPos๋ฅผ ๊ฐ์ฅ ๋จผ ์ง์ ์ด๋ผ๊ณ ์๊ฐํ๋ค.
void depth_first_search(int N, int V)
{
int i = 0, j = 0, distance = 0;
int row = V;
push(V);
while (is_empty())
{
visited[row] = 1;
if (adj_mat[row*(N + 1) + i] && !visited[i])
{
push(i);
sPos[j] = i;
distance += adj_mat[row*(N + 1) + i];
sMax[j++] = distance;
row = i;
i = 0;
}
if (i == N)
{
pop();
distance -= adj_mat[row*(N + 1) + top()];
row = top();
i = 0;
}
i++;
}
}
void find_diameter(int N)
{
int i, sPos_, sMax_ = 0;
depth_first_search(N, 1);
for (i = 0; i < N+1; i++)
{
visited[i] = 0;
if (sMax[i] > sMax_)
{
sMax_ = sMax[i];
sPos_ = sPos[i];
}
}
depth_first_search(N, sPos_);
for (i = 0; i < N + 1; i++)
{
if (sMax[i] > sMax_)
{
sMax_ = sMax[i];
sPos_ = sPos[i];
}
}
printf("%d", sMax_);
}
04 ์ ์ฒด ์ฝ๋
// Day3 2018.08.02
// 1967๋ฒ : ํธ๋ฆฌ์ ์ง๋ฆ (The diameter of the tree)
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#define scanf scanf_s
typedef struct _dnode {
int key;
struct _dnode *prev;
struct _dnode *next;
}dnode;
dnode *head, *tail;
void init_node();
int push(int k);
int pop();
void clear_node();
int is_empty();
int top();
char *adj_mat;
bool *visited;
int *sMax, *sPos;
void adjacent_matrix(int V);
void print_matrix(int N);
void depth_first_search(int N, int V);
void find_diameter(int V);
int main()
{
int N;
scanf("%d", &N); // ๋
ธ๋์ ๊ฐ์ 1 ~ 10,000
adj_mat = (char *)calloc((N + 1)*(N + 1), sizeof(char));
visited = (bool *)calloc(N + 1, sizeof(bool));
sMax = (int *)calloc(N + 1, sizeof(int));
sPos = (int *)calloc(N + 1, sizeof(int));
init_node();
adjacent_matrix(N);
//print_matrix(N);
//printf("- - - - - - - \n");
find_diameter(N);
// finish
free(visited);
free(adj_mat);
clear_node();
return 0;
}
void adjacent_matrix(int N)
{
int i, parent, child, weight;
for (i = 0; i < N - 1; i++)
{
scanf("%d %d %d", &parent, &child, &weight);
adj_mat[parent*(N + 1) + child] = weight;
adj_mat[child*(N + 1) + parent] = weight;
}
}
void print_matrix(int N)
{
int i, j;
// print
for (i = 0; i < N + 1; i++)
{
printf("row %3d > ", i);
for (j = 0; j < N + 1; j++)
{
printf("%3d ", adj_mat[i*(N + 1) + j]);
}
printf("\n");
}
}
void depth_first_search(int N, int V)
{
int i = 0, j = 0, distance = 0;
int row = V;
push(V);
//printf("> push %d\n", push(V));
while (is_empty())
{
visited[row] = 1;
if (adj_mat[row*(N + 1) + i] && !visited[i])
{
push(i);
//printf("> push %d now %d next %d weight %d ", push(i), row, i, adj_mat[row*(N+1)+i]);
sPos[j] = i;
distance += adj_mat[row*(N + 1) + i];
//printf("-> distance %d\n", distance);
sMax[j++] = distance;
row = i;
i = 0;
}
if (i == N)
{
pop();
//printf("> pop %d ", pop());
//printf(" now %d prev %d weight %d ", row, top(), adj_mat[row*(N+1)+top()]);
distance -= adj_mat[row*(N + 1) + top()];
//printf("-> distance %d\n", distance);
row = top();
i = 0;
}
i++;
}
}
void find_diameter(int N)
{
int i, sPos_, sMax_ = 0;
depth_first_search(N, 1);
for (i = 0; i < N+1; i++)
{
visited[i] = 0;
//printf("sMax %d sPos %d\n", sMax[i], sPos[i]);
if (sMax[i] > sMax_)
{
sMax_ = sMax[i];
sPos_ = sPos[i];
}
}
//printf("sMAX_ %d sPos_ %d\n", sMax_, sPos_);
depth_first_search(N, sPos_);
for (i = 0; i < N + 1; i++)
{
if (sMax[i] > sMax_)
{
sMax_ = sMax[i];
sPos_ = sPos[i];
}
}
printf("%d", sMax_);
//printf("sMAX_ %d sPos_ %d\n", sMax_, sPos_);
}
void init_node()
{
head = (dnode *)calloc(1, sizeof(dnode));
tail = (dnode *)calloc(1, sizeof(dnode));
head->prev = head;
head->next = tail;
tail->prev = head;
tail->next = tail;
}
/* * * * * * * * * * * * *
** Stack push and pop * *
** * * * * * * * * * * * */
int push(int k)
{
dnode *t;
if ((t = (dnode *)malloc(sizeof(dnode))) == NULL)
{
printf("Out of memory !\n");
return -1;
}
t->key = k;
head->next->prev = t;
t->next = head->next;
t->prev = head;
head->next = t;
return k;
}
int pop()
{
dnode *t;
int k;
if (head->next == tail)
{
printf("Stack underflow !\n");
return -1;
}
t = head->next;
k = t->key;
head->next = t->next;
t->next->prev = head;
free(t);
return k;
}
void clear_node()
{
dnode *t, *s;
t = head->next;
while (t != tail)
{
s = t;
t = t->next;
free(s);
}
head->next = tail;
tail->prev = head;
}
int is_empty()
{
if (head->next == tail)
{
//printf("Linked list is empty !\n");
return 0;
}
return 1;
}
int top()
{
dnode *t;
t = head->next;
if (t == tail)
return -1;
return t->key;
}
99 ์ฐธ๊ณ ์๋ฃ
- [๋ฐฑ์ค ์๊ณ ๋ฆฌ์ฆ 1967๋ฒ : ํธ๋ฆฌ์ ์ง๋ฆ] https://www.acmicpc.net/problem/1967
- [ํธ๋ฆฌ์ ์ง๋ฆ ๊ตฌํ๋ ๋ฒ์ ์ฆ๋ช ] http://blog.myungwoo.kr/112
728x90
728x90
'๐ Algorithm > ์๊ณ ๋ฆฌ์ฆ-Python' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๊ณ ๋ฆฌ์ฆ/Python] ํ๋ก๊ทธ๋๋จธ์ค - ํ๊ฒ ๋๋ฒ (DFS) (0) | 2021.03.06 |
---|---|
[์๊ณ ๋ฆฌ์ฆ/Python] BOJ 1158 - ์์ธํธ์ค ๋ฌธ์ (๊ธฐ์ด ์๋ฃ๊ตฌ์กฐ) (2) | 2021.03.06 |
[์๊ณ ๋ฆฌ์ฆ] Day3 - 2309๋ฒ ์ผ๊ณฑ ๋์์ด (0) | 2018.08.08 |
[์๊ณ ๋ฆฌ์ฆ] Day3 - 1260๋ฒ DFS์ BFS (0) | 2018.08.08 |
[์๊ณ ๋ฆฌ์ฆ] Day2 - 2750๋ฒ ์ ์ ๋ ฌํ๊ธฐ (0) | 2018.08.04 |