๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ Algorithm/์•Œ๊ณ ๋ฆฌ์ฆ˜-Python

[์•Œ๊ณ ๋ฆฌ์ฆ˜] Day3 - 1967๋ฒˆ ํŠธ๋ฆฌ์˜ ์ง€๋ฆ„

by Danna 2018. 8. 8.
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 ์ฐธ๊ณ  ์ž๋ฃŒ



728x90
728x90