μƒˆμ†Œμ‹

μ•Œκ³ λ¦¬μ¦˜/Programmers

[ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€] μ „λ ₯망을 λ‘˜λ‘œ λ‚˜λˆ„κΈ° C++

  • -
728x90

 

1. 문제

좜처:https://school.programmers.co.kr/learn/courses/30/lessons/86971

n개의 μ†‘전탑이 μ „선을 ν†΅ν•΄ ν•˜λ‚˜μ˜ νŠΈλ¦¬ ν˜•νƒœλ‘œ μ—°κ²°λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. λ‹Ήμ‹ μ€ μ΄ μ „μ„ λ“€ μ€‘ ν•˜λ‚˜λ₯Ό λŠμ–΄μ„œ ν˜„μž¬μ˜ μ „λ ₯망 λ„€νŠΈμ›Œν¬λ₯Ό 2개둜 λΆ„ν• ν•˜λ €κ³  ν•©λ‹ˆλ‹€. μ΄λ•Œ, λ‘ μ „λ ₯망이 κ°–κ²Œ λ˜λŠ” μ†‘μ „νƒ‘μ˜ κ°œμˆ˜λ₯Ό μ΅œλŒ€ν•œ λΉ„μŠ·ν•˜κ²Œ λ§žμΆ”κ³ μž ν•©λ‹ˆλ‹€.

μ†‘μ „νƒ‘μ˜ κ°œμˆ˜ n, κ·Έλ¦¬κ³  μ „μ„  μ •λ³΄ wiresκ°€ λ§€κ°œλ³€μˆ˜λ‘œ μ£Όμ–΄μ§‘λ‹ˆλ‹€. μ „μ„ λ“€ μ€‘ ν•˜λ‚˜λ₯Ό λŠμ–΄μ„œ μ†‘전탑 κ°œμˆ˜κ°€ κ°€λŠ₯ν•œ λΉ„μŠ·ν•˜λ„λ‘ λ‘ μ „λ ₯망으둜 λ‚˜λˆ„μ—ˆμ„ λ•Œ, λ‘ μ „λ ₯망이 κ°€μ§€κ³  μžˆλŠ” μ†‘전탑 κ°œμˆ˜μ˜ μ°¨μ΄(μ ˆλŒ€κ°’)λ₯Ό return ν•˜λ„둝 solution ν•¨μˆ˜λ₯Ό μ™„μ„±ν•΄μ£Όμ„Έμš”.

2. μ½”λ“œ

#include <string>
#include <vector>

using namespace std;

//dfs, visited 방법

int graph[101][101];
int visited[101];

int dfs(int cur, int n)
{
    if(visited[cur]) return 0;      //ν•œλ²ˆ λ°©λ¬Έν•œ 곳은 재방문 X
    int child=1;      //ν•˜μœ„ λ…Έλ“œμ˜ 갯수
    visited[cur]=true;
    for(int i=1;i<=n;i++)
    {
        if(graph[cur][i])       //μ—°κ²°, 간적 μ—†λŠ” 곳만
        {
            child+=dfs(i,n);
        }
    }
    return child;
}

void setGraph(int x,int y,int value)
{
    graph[x][y]=value;
    graph[y][x]=value;
}

int solution(int n, vector<vector<int>> wires) {
    int answer = 101;
    
    //μ—°κ²°λ˜μ–΄ μžˆλŠ” λͺ¨λ“  솑전탑 1둜 μ΄ˆκΈ°ν™”
    for(int i=0;i<wires.size();i++){
        setGraph(wires[i][0],wires[i][1],1);
    }
    
    for(int i=0;i<wires.size();i++){
        //λ°©λ¬Έ λ°°μ—΄ μ΄ˆκΈ°ν™”
        fill_n(visited,101,false);
        
        //λŠμ„ μ „μ„  0으둜 λ§Œλ“€μ–΄μ£ΌκΈ° -> μ „μ„  끊기
        setGraph(wires[i][0],wires[i][1],0);

        vector<int> diff;
        for(int i=1;i<=n;i++)
        {
            int tmp=dfs(i,n);       //깊이 탐색
            if(!tmp)continue;       //λ°©λ¬Έν•œ 경우 μƒλž΅
            diff.push_back(tmp);
        }
        answer = min(answer, abs(diff[0]-diff[1]));
        if(answer==0)break;
        //μ›μƒνƒœλ‘œ λŒλ €λ†“κΈ°
        setGraph(wires[i][0],wires[i][1],1);
    }
    
    return answer;
}

 

3. ν•΄μ„€

//dfs, visited 방법

int solution(int n, vector<vector<int>> wires) {
    int answer = 101;
    
    //μ—°κ²°λ˜μ–΄ μžˆλŠ” λͺ¨λ“  솑전탑 1둜 μ΄ˆκΈ°ν™”
    for(int i=0;i<wires.size();i++){
        setGraph(wires[i][0],wires[i][1],1);
    }
    
    for(int i=0;i<wires.size();i++){
        //λ°©λ¬Έ λ°°μ—΄ μ΄ˆκΈ°ν™”
        fill_n(visited,101,false);
        
        //λŠμ„ μ „μ„  0으둜 λ§Œλ“€μ–΄μ£ΌκΈ° -> μ „μ„  끊기
        setGraph(wires[i][0],wires[i][1],0);

        vector<int> diff;
        for(int i=1;i<=n;i++)
        {
            int tmp=dfs(i,n);       //깊이 탐색
            if(!tmp)continue;       //λ°©λ¬Έν•œ 경우 μƒλž΅
            diff.push_back(tmp);
        }
        answer = min(answer, abs(diff[0]-diff[1]));
        if(answer==0)break;
        //μ›μƒνƒœλ‘œ λŒλ €λ†“κΈ°
        setGraph(wires[i][0],wires[i][1],1);
    }
    
    return answer;
}

dfsλ₯Ό μ΄μš©ν•΄μ„œ ν’€μ–΄μ•Όν•˜λŠ” λ¬Έμ œμ΄λ‹€. μ²˜μŒμ— 문제λ₯Ό μ ‘κ·Όν•  λ•Œ dp둜 μ ‘κ·Όν•˜μ—¬μ„œ λ…Έλ“œμ˜ ν•˜μœ„ 갯수λ₯Ό λˆ„μ ν•˜μ˜€μ—ˆλŠ”λ° ν•΄λ‹Ή κ²½μš°λŠ” λ…Έλ“œκ°€ μ •λ ¬λ˜μ–΄ μžˆμ§€ μ•Šμ„ λ•Œ μ ν•©ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μ‚¬μš©ν•  수 μ—†μ—ˆλ‹€.

ν‘ΈλŠ” μˆœμ„œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

1. λ¨Όμ € μ—°κ²°λ˜μ–΄ μžˆλŠ” λͺ¨λ“  솑전탑듀을 2차원 배열에 1둜 ν‘œμ‹œν•΄μ€λ‹ˆλ‹€.

    //μ—°κ²°λ˜μ–΄ μžˆλŠ” λͺ¨λ“  솑전탑 1둜 μ΄ˆκΈ°ν™”
    for(int i=0;i<wires.size();i++){
        setGraph(wires[i][0],wires[i][1],1);
    }

2. 0~n번째 솑전탑을 각각 λŠλŠ” for 문을 μ΄μš©ν•˜μ—¬ n번 λŒλ €μ€λ‹ˆλ‹€.

    for(int i=0;i<wires.size();i++){

3. λ°©λ¬Έ 배열을 μ΄ˆκΈ°ν™” ν•΄μ£Όκ³ , 2차원 λ°°μ—΄μ—μ„œ λŠμ„ 솑전탑을 0으둜 λ§Œλ“€μ–΄μ€λ‹ˆλ‹€.

        //λ°©λ¬Έ λ°°μ—΄ μ΄ˆκΈ°ν™”
        fill_n(visited,101,false);
        
        //λŠμ„ μ „μ„  0으둜 λ§Œλ“€μ–΄μ£ΌκΈ° -> μ „μ„  끊기
        setGraph(wires[i][0],wires[i][1],0);

4. dfs 탐색을 톡해 λ°©λ¬Έν•˜μ§€ μ•Šκ³  연결이 λŠμ–΄μ§€μ§€ μ•Šμ€ κ³³κΉŒμ§€ 탐색을 ν•˜μ—¬ ν•˜μœ„ λ…Έλ“œμ˜ 갯수λ₯Ό λ°˜ν™˜ν•˜κ³  κ·Έ κ°’λ“€μ˜ 차이λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

        vector<int> diff;
        for(int i=1;i<=n;i++)
        {
            int tmp=dfs(i,n);       //깊이 탐색
            if(!tmp)continue;       //λ°©λ¬Έν•œ 경우 μƒλž΅
            diff.push_back(tmp);
        }
        answer = min(answer, abs(diff[0]-diff[1]));
        if(answer==0)break;
        //μ›μƒνƒœλ‘œ λŒλ €λ†“κΈ°
        setGraph(wires[i][0],wires[i][1],1);

 

 

 

 

λ°˜μ‘ν˜•
Contents

ν¬μŠ€νŒ… μ£Όμ†Œλ₯Ό λ³΅μ‚¬ν–ˆμŠ΅λ‹ˆλ‹€

이 글이 도움이 λ˜μ—ˆλ‹€λ©΄ 곡감 λΆ€νƒλ“œλ¦½λ‹ˆλ‹€.