<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>네론's 성장일지</title>
    <link>https://iamneveralone.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 9 Aug 2026 04:11:04 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>neveralone</managingEditor>
    <image>
      <title>네론's 성장일지</title>
      <url>https://tistory1.daumcdn.net/tistory/5455006/attach/6c97c4e077b24831bf6df19b5ce9af87</url>
      <link>https://iamneveralone.tistory.com</link>
    </image>
    <item>
      <title>Windows 11에서 Linux (Ubuntu) 설치 및 실행하기</title>
      <link>https://iamneveralone.tistory.com/63</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;920&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJjCNQ/btsNrdLaHJv/tWR8aibJ0SBTmmorkREuiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJjCNQ/btsNrdLaHJv/tWR8aibJ0SBTmmorkREuiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJjCNQ/btsNrdLaHJv/tWR8aibJ0SBTmmorkREuiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJjCNQ%2FbtsNrdLaHJv%2FtWR8aibJ0SBTmmorkREuiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;554&quot; height=&quot;277&quot; data-origin-width=&quot;920&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;WSL이란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;/b&gt;WSL은 Windows Service for Linux의 약자로써, 별도의&amp;nbsp;가상&amp;nbsp;머신&amp;nbsp;또는&amp;nbsp;이중&amp;nbsp;부팅&amp;nbsp;없이&amp;nbsp;Windows&amp;nbsp;컴퓨터에서&amp;nbsp;Linux&amp;nbsp;환경을&amp;nbsp;실행할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;Windows의&amp;nbsp;기능입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자는 Windows 환경에서 Linux&amp;nbsp;배포판을&amp;nbsp;선택하여&amp;nbsp;설치하고&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linux 배포판의 대표적인 예시로는 Ubuntu, Debian, Fedora 등이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WSL을 이용하여 Ubuntu 배포판을 설치하고 실행하는 과정을 설명드리겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[Linux용 Windows 하위 시스템] 활성화&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Windows 기능 켜기/끄기 - Linux용 Windows 하위 시스템을 활성화해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;383&quot; data-origin-height=&quot;386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v007j/btsNrzhnomB/9V8ojkKkIVlziOOoglIk41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v007j/btsNrzhnomB/9V8ojkKkIVlziOOoglIk41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v007j/btsNrzhnomB/9V8ojkKkIVlziOOoglIk41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv007j%2FbtsNrzhnomB%2F9V8ojkKkIVlziOOoglIk41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;383&quot; height=&quot;386&quot; data-origin-width=&quot;383&quot; data-origin-height=&quot;386&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;WSL 및 Ubuntu 설치&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 Windows Powershell을 관리자 모드로 열어줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;453&quot; data-origin-height=&quot;417&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qUOga/btsNtfnY0sk/NpIGsSUCO2jG5fzBmQL23k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qUOga/btsNtfnY0sk/NpIGsSUCO2jG5fzBmQL23k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qUOga/btsNtfnY0sk/NpIGsSUCO2jG5fzBmQL23k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqUOga%2FbtsNtfnY0sk%2FNpIGsSUCO2jG5fzBmQL23k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;316&quot; height=&quot;291&quot; data-origin-width=&quot;453&quot; data-origin-height=&quot;417&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;wsl --install 명령어를 실행하면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;WSL&amp;nbsp;및&amp;nbsp;Linux의&amp;nbsp;기본&amp;nbsp;Ubuntu&amp;nbsp;배포를&amp;nbsp;설치합니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1743587896278&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl --install&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;696&quot; data-origin-height=&quot;115&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JSh4V/btsM6CjynQI/Vv6yQZMjhAZ4CBCY2WW9wK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JSh4V/btsM6CjynQI/Vv6yQZMjhAZ4CBCY2WW9wK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JSh4V/btsM6CjynQI/Vv6yQZMjhAZ4CBCY2WW9wK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJSh4V%2FbtsM6CjynQI%2FVv6yQZMjhAZ4CBCY2WW9wK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;581&quot; height=&quot;96&quot; data-origin-width=&quot;696&quot; data-origin-height=&quot;115&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본으로 설치되는 Ubuntu 이외에 다른 배포판을 설치하고 싶은 경우, 다음 명령어를 실행하면 설치 가능한 유효한 배포판 목록을 확인할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1745139712536&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl --list --online&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ruOJd/btsNrzaGm0B/AskbIWa2rKDkkT6KHE5VRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ruOJd/btsNrzaGm0B/AskbIWa2rKDkkT6KHE5VRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ruOJd/btsNrzaGm0B/AskbIWa2rKDkkT6KHE5VRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FruOJd%2FbtsNrzaGm0B%2FAskbIWa2rKDkkT6KHE5VRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;482&quot; height=&quot;384&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 명령어를 통해 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;선택한 배포판을 &lt;/span&gt;설치할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1745140193039&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl --install &amp;lt;Distribution Name&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;wsl --list --verbose 명령어를 실행하면 현재 설치되어 있는 Linux 배포판 목록을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 간결하게 wsl -l -v 명령어를 실행해도 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1745143293749&quot; class=&quot;brainfuck&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;wsl --list --verbose&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;483&quot; data-origin-height=&quot;200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/doJRDX/btsM5TGj0eJ/ivjJza96ylqm378dFvztlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/doJRDX/btsM5TGj0eJ/ivjJza96ylqm378dFvztlk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/doJRDX/btsM5TGj0eJ/ivjJza96ylqm378dFvztlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdoJRDX%2FbtsM5TGj0eJ%2FivjJza96ylqm378dFvztlk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;420&quot; height=&quot;174&quot; data-origin-width=&quot;483&quot; data-origin-height=&quot;200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;안내해준대로 wsl.exe -d Ubuntu 명령어를 실행하면 Ubuntu를 시작할 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Ubuntu 최초 시작 시 account와 password 설정이 필요합니다. (password는 입력해도 콘솔에서는 보이지 않습니다.)&lt;/p&gt;
&lt;pre id=&quot;code_1743589960861&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl.exe -d Ubuntu&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;836&quot; data-origin-height=&quot;523&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AMeAU/btsNsjSpvF0/U1OU4CMjyOr1IaJ7Ffs1NK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AMeAU/btsNsjSpvF0/U1OU4CMjyOr1IaJ7Ffs1NK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AMeAU/btsNsjSpvF0/U1OU4CMjyOr1IaJ7Ffs1NK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAMeAU%2FbtsNsjSpvF0%2FU1OU4CMjyOr1IaJ7Ffs1NK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;674&quot; height=&quot;422&quot; data-origin-width=&quot;836&quot; data-origin-height=&quot;523&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;exit 명령어를 통해 Ubuntu를 종료하고 다시 PowerShell로 돌아올 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1745140332167&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;exit&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;516&quot; data-origin-height=&quot;96&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcgRSy/btsM66YM56A/KuuDHoZQc1Zfb4ZJIKHs7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcgRSy/btsM66YM56A/KuuDHoZQc1Zfb4ZJIKHs7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcgRSy/btsM66YM56A/KuuDHoZQc1Zfb4ZJIKHs7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcgRSy%2FbtsM66YM56A%2FKuuDHoZQc1Zfb4ZJIKHs7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;403&quot; height=&quot;75&quot; data-origin-width=&quot;516&quot; data-origin-height=&quot;96&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Windows Terminal 접속 및 세팅&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;426&quot; data-origin-height=&quot;87&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TMwRh/btsNtqJmMbr/9SLlkEgKj4IeshaFb7TQK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TMwRh/btsNtqJmMbr/9SLlkEgKj4IeshaFb7TQK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TMwRh/btsNtqJmMbr/9SLlkEgKj4IeshaFb7TQK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTMwRh%2FbtsNtqJmMbr%2F9SLlkEgKj4IeshaFb7TQK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;372&quot; height=&quot;76&quot; data-origin-width=&quot;426&quot; data-origin-height=&quot;87&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시 Windows Terminal이 설최되어 있지 않다면, Microsoft Store에서 설치해주면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;402&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k9Y91/btsNrxDTaBf/L3URbNFv7Dq745cnSkTRB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k9Y91/btsNrxDTaBf/L3URbNFv7Dq745cnSkTRB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k9Y91/btsNrxDTaBf/L3URbNFv7Dq745cnSkTRB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk9Y91%2FbtsNrxDTaBf%2FL3URbNFv7Dq745cnSkTRB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;341&quot; height=&quot;317&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;402&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞선 과정에서 Ubuntu를 정상적으로 설치 완료했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그에 따라 터미널에 접속한 후 탭 옆에 [+] 버튼을 누르면, 이제 Ubuntu를 선택할 수 있게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;557&quot; data-origin-height=&quot;478&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yXoum/btsNskKx2MM/r3LkBFKBPDFkpuAaN10FS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yXoum/btsNskKx2MM/r3LkBFKBPDFkpuAaN10FS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yXoum/btsNskKx2MM/r3LkBFKBPDFkpuAaN10FS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyXoum%2FbtsNskKx2MM%2Fr3LkBFKBPDFkpuAaN10FS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;388&quot; height=&quot;333&quot; data-origin-width=&quot;557&quot; data-origin-height=&quot;478&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[설정]에서 기본 프로필을 Ubuntu로 설정해주면 이제 터미널 접속 시 기본적으로 Ubuntu로 접속할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1158&quot; data-origin-height=&quot;191&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czjcgN/btsNtkCAZZz/y9sqFJU5K8edaoagri11H1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czjcgN/btsNtkCAZZz/y9sqFJU5K8edaoagri11H1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czjcgN/btsNtkCAZZz/y9sqFJU5K8edaoagri11H1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczjcgN%2FbtsNtkCAZZz%2Fy9sqFJU5K8edaoagri11H1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;721&quot; height=&quot;119&quot; data-origin-width=&quot;1158&quot; data-origin-height=&quot;191&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널을 접속하면 PowerShell에서 Ubuntu 최초 실행 시 설정했던 account 기반으로 자동 접속되는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;172&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XWZpP/btsNsD3omqJ/aLcSKv3tJHmxnjvsYkYFeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XWZpP/btsNsD3omqJ/aLcSKv3tJHmxnjvsYkYFeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XWZpP/btsNsD3omqJ/aLcSKv3tJHmxnjvsYkYFeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXWZpP%2FbtsNsD3omqJ%2FaLcSKv3tJHmxnjvsYkYFeK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;777&quot; height=&quot;131&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;172&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 명령어 실행을 통해 현재 Ubuntu 버전이 24.04.2 LTS임을 확인할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1743589160033&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;lsb_release -a&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;473&quot; data-origin-height=&quot;135&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZ9hbQ/btsM5zg2WUU/7HRres0XBHkV0pWwuNLOx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZ9hbQ/btsM5zg2WUU/7HRres0XBHkV0pWwuNLOx0/img.png&quot; data-alt=&quot;Ubuntu 버전 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZ9hbQ/btsM5zg2WUU/7HRres0XBHkV0pWwuNLOx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZ9hbQ%2FbtsM5zg2WUU%2F7HRres0XBHkV0pWwuNLOx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;385&quot; height=&quot;110&quot; data-origin-width=&quot;473&quot; data-origin-height=&quot;135&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Ubuntu 버전 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Linux</category>
      <author>neveralone</author>
      <guid isPermaLink="true">https://iamneveralone.tistory.com/63</guid>
      <comments>https://iamneveralone.tistory.com/63#entry63comment</comments>
      <pubDate>Sun, 20 Apr 2025 19:03:22 +0900</pubDate>
    </item>
    <item>
      <title>AWS 정리</title>
      <link>https://iamneveralone.tistory.com/62</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Amazon Appflow&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SaaS (Software as a Service) 애플리케이션과 AWS 서비스 간에 데이터를 안전하게 전송할 수 있는 완전 관리형 통합 서비스&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SaaS 애플리케이션 : Salesforce, SAP, Zendesk, Slack, ServiceNow 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AWS 서비스 : Amazon S3, Amazon Redshift 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;완전 관리형 서비스이므로 운영 오버헤드가 적음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;NAT Gateway&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NAT : Network Address Translation, 네트워크 주소 변환&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;외부 서비스에서 private subnet의 인스턴스로 접근할 수 없게 하되, private subnet의 인스턴스에서는 외부 서비스로 접근할 수 있게 해주는 서비스&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;324&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CCftn/btsLfXDcUVP/fBrNNBd7ni4iTTJBhStRW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CCftn/btsLfXDcUVP/fBrNNBd7ni4iTTJBhStRW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CCftn/btsLfXDcUVP/fBrNNBd7ni4iTTJBhStRW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCCftn%2FbtsLfXDcUVP%2FfBrNNBd7ni4iTTJBhStRW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;682&quot; height=&quot;324&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;324&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;VPC Endpoint&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;VPC와 AWS 서비스 사이의 통신을 비공개로 연결할 수 있도록 해주는 서비스&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Public IP 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VPC와 기타 서비스 간의 트래픽은 AWS 네트워크를 벗어나지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex)&lt;br /&gt;VPC Endpoint 없으면 EC2 인스턴스 -&amp;gt; S3 액세스할 때, EC2는 NAT와 Internet Gateway를 통해 외부로 나가 S3 접속&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(EC2와 S3 둘 다 AWS 서비스라고 해서 둘이 당연히 내부 통신한다고 생각하면 안 됨)&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- EC2, RDS 등의 서비스는 ENI (Elastic Network Interface, 가상의 랜카드)를 탑재하고, 이 ENI에 Public 혹은 Private IP를 부여하며 VPC 안에 존재&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- S3는 AWS Region 안에 위치하는 건 맞지만 VPC 내부에 위치하지 않고 공인 IP를 통해 외부에서 접근하는 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 즉, S3 등의 서비스를 이용하려면 외부 인터넷을 이용해야 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 중요 정보가 외부 인터넷을 타는 것을 꺼린다면 VPC Endpoint를 고려해볼 수 있음&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;422&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1s5Xk/btsLfmwMXTA/HRbzWLiu18cZCkNqxMrHbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1s5Xk/btsLfmwMXTA/HRbzWLiu18cZCkNqxMrHbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1s5Xk/btsLfmwMXTA/HRbzWLiu18cZCkNqxMrHbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1s5Xk%2FbtsLfmwMXTA%2FHRbzWLiu18cZCkNqxMrHbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;558&quot; height=&quot;399&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;422&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;VPC Endpoint 종류&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Interface Endpoint (ENI 기반)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Private IP 주소 생성하여 서비스 연결시켜줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- SQS, SNS 등 여러 서비스 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Interface Endpoint는 private subnet 안에 위치&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;361&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RD57D/btsLfOzw9hO/v9HikfEpvuUt2693CbpMUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RD57D/btsLfOzw9hO/v9HikfEpvuUt2693CbpMUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RD57D/btsLfOzw9hO/v9HikfEpvuUt2693CbpMUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRD57D%2FbtsLfOzw9hO%2Fv9HikfEpvuUt2693CbpMUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;649&quot; height=&quot;271&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;361&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Gateway Endpoint&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- S3 및 DynamoDB 등을 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Gateway Endpoint는 private subnet 밖에 위치&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;964&quot; data-origin-height=&quot;411&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/camuns/btsLe3YyL64/bK33z9A4tjENUIGEHSh5N0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/camuns/btsLe3YyL64/bK33z9A4tjENUIGEHSh5N0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/camuns/btsLe3YyL64/bK33z9A4tjENUIGEHSh5N0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcamuns%2FbtsLe3YyL64%2FbK33z9A4tjENUIGEHSh5N0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;691&quot; height=&quot;295&quot; data-origin-width=&quot;964&quot; data-origin-height=&quot;411&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;AWS Direct Connect&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;회사 내부 네트워크 혹은 기존 데이터 센터 환경의 온프레미스 IT 자원과 AWS 클라우드 자원을 전용 회선으로 연결하여, 하이브리드 환경을 구축할 수 있는 서비스&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, AWS 클라우드에 직접적으로 연결할 수 있게 해주는 네트워크 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자는 인터넷을 경유하지 않고 AWS 네트워크(VPC)와 사용자 네트워크를 직접 연결할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 고성능 네트워킹 - Direct Connect는 고정 대역폭 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 보안성 향상 - 데이터가 인터넷을 경유하지 않음, 민감한 데이터 다루는 기업에게 중요한 장점&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 지연 시간 감소 - 인터넷 경유하지 않으므로 네트워크 지연 시간 감소&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 비용 절감 - 대량의 데이터 주고받는 경우 효율적&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;924&quot; data-origin-height=&quot;502&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWcoO9/btsLf9wBXAt/ewHGnGkiOAIsohRia0roT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWcoO9/btsLf9wBXAt/ewHGnGkiOAIsohRia0roT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWcoO9/btsLf9wBXAt/ewHGnGkiOAIsohRia0roT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWcoO9%2FbtsLf9wBXAt%2FewHGnGkiOAIsohRia0roT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;364&quot; data-origin-width=&quot;924&quot; data-origin-height=&quot;502&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Amazon SNS (Simple Notification Service)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Amazon SQS (Simple Queue Service)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Lambda&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Amazon API Gateway&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;규모에 상관없이 API 생성, 유지관리, 모니터링, 보호를 할 수 있게 해주는 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 API들의 &quot;대문(gateway)&quot; 역할&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 클라이언트는 각 서비스의 endpoint 대신 API Gateway로 요청을 전달&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;896&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpZUml/btsLlYO8uZl/Swk9CrLBZn0L0D8YSZ2Qb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpZUml/btsLlYO8uZl/Swk9CrLBZn0L0D8YSZ2Qb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpZUml/btsLlYO8uZl/Swk9CrLBZn0L0D8YSZ2Qb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpZUml%2FbtsLlYO8uZl%2FSwk9CrLBZn0L0D8YSZ2Qb1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;613&quot; height=&quot;429&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;896&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;API Gateway의 Endpoint 종류&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Edge - Optimized Endpoint : 전세계 사용자에게 최적의 경험 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Regional Endpoint : 특정 region에서만 동작하도록 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Private Endpoint : 내부 네트워크(ex. VPC)에서만 액세스할 수 있는 API 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;API Gateway의 사용자 지정 도메인 이름 HTTPS 보안&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AWS Certificate Manager (ACM)&lt;/b&gt;과의 통합을 통해 사용자 지정 Domain Name에 대한 HTTPS 보안을 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 API Gateway에 대한 보안 접근을 보장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Edge - Optimized Endpoint 사용하는 경우, 인증서는 us-ease-1에서 관리되어야 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Regional Endpoint 사용하는 경우, 인증서는 해당 API Gateway의 region에서 관리되어야 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;AWS Certificate Manager (ACM)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS 서비스 및 연결된 내부 리소스에 사용할 공인 및 사설 SSL/TLS 인증서를 손쉽게 프로비저닝, 관리 및 배포 가능할 수 있게 해주는 서비스&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNJfHt/btsLleSzPK0/3kQMdAIAkok46LaK2KtKI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNJfHt/btsLleSzPK0/3kQMdAIAkok46LaK2KtKI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNJfHt/btsLleSzPK0/3kQMdAIAkok46LaK2KtKI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNJfHt%2FbtsLleSzPK0%2F3kQMdAIAkok46LaK2KtKI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;659&quot; height=&quot;348&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;475&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Amazon Rekognition&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지/동영상에 대한 시각적 분석 기능을 쉽게 추가할 수 있게 해주는 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부적절하거나 불쾌감을 주는 콘텐츠를 감지할 때 사용될 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;AWS Fargate&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버리스 컴퓨팅 엔진&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Amazon Elastic Container Service (ECS) 및 Amazon Elastic Kubernetes (EKS)와 연동되는 컨테이너용 서버리스 컴퓨팅 엔진&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Fargate를 사용하면 서버를 프로비저닝하고 관리할 필요가 없기 때문에 애플리케이션 구축에 쉽게 집중할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Amazon Kinesis Data Streams&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대량의 스트림 데이터 수집&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;모든 규모에서 실시간으로 다양한 스트리밍 데이터를 저장하고 수집하는 완전관리형 서버리스 데이터 스트리밍 서비스&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;391&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bC6gPi/btsLmsi2m4s/fZVkSRIgyFO0fk4qKGXwI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bC6gPi/btsLmsi2m4s/fZVkSRIgyFO0fk4qKGXwI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bC6gPi/btsLmsi2m4s/fZVkSRIgyFO0fk4qKGXwI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbC6gPi%2FbtsLmsi2m4s%2FfZVkSRIgyFO0fk4qKGXwI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;634&quot; height=&quot;194&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;391&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Amazon Kinesis Data Firehose&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;데이터를 이동시키는 서비스&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;소스에서 데이터를 가지고 오는데 대부분의 경우 Kinesis Data Streams&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Firehose로부터 데이터를 받는 AWS 수신처는 셋 중 하나&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Amazon S3&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Amazon Redshift&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Amazon Elasticsearch Service&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 외 다양한 3rd Party나 custom HTTP가 될 수도 있음&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;493&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d0Zu3u/btsLmLvTD89/giInhtmqfexR2bKGAAU9o1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d0Zu3u/btsLmLvTD89/giInhtmqfexR2bKGAAU9o1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d0Zu3u/btsLmLvTD89/giInhtmqfexR2bKGAAU9o1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd0Zu3u%2FbtsLmLvTD89%2FgiInhtmqfexR2bKGAAU9o1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;782&quot; height=&quot;321&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;493&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Amazon Redshift&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;PB(페타 바이트) 규모의 &quot;데이터 웨어하우스&quot; 서비스&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 시스템에서 데이터를 수집하고 통합 및 저장하여 분석에 사용하는 데이터베이스&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;344&quot; data-origin-height=&quot;470&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csd569/btsLmHNTREC/2jdUx2nMxpsTELsruhwxg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csd569/btsLmHNTREC/2jdUx2nMxpsTELsruhwxg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csd569/btsLmHNTREC/2jdUx2nMxpsTELsruhwxg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcsd569%2FbtsLmHNTREC%2F2jdUx2nMxpsTELsruhwxg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;319&quot; height=&quot;436&quot; data-origin-width=&quot;344&quot; data-origin-height=&quot;470&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Amazon Athena&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;표준 SQL을 사용하여 Amazon S3에 저장된 데이터를 간편하게 분석할 수 있는 대화식 쿼리 서비스&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버리스 서비스이므로 관리할 필요 없음, 실행한 쿼리에 대해서만 비용 지불&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;654&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhMQ2t/btsLmgiSKWx/ZfuiqYN32elgqzMwC6QYdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhMQ2t/btsLmgiSKWx/ZfuiqYN32elgqzMwC6QYdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhMQ2t/btsLmgiSKWx/ZfuiqYN32elgqzMwC6QYdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhMQ2t%2FbtsLmgiSKWx%2FZfuiqYN32elgqzMwC6QYdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;819&quot; height=&quot;383&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;654&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <author>neveralone</author>
      <guid isPermaLink="true">https://iamneveralone.tistory.com/62</guid>
      <comments>https://iamneveralone.tistory.com/62#entry62comment</comments>
      <pubDate>Sun, 29 Dec 2024 07:45:36 +0900</pubDate>
    </item>
    <item>
      <title>개인 학습 경험 정리</title>
      <link>https://iamneveralone.tistory.com/61</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 6개월 동안 개인적으로 학습한 경험을 정리해보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Kotlin 학습&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Obsidian에 정리했던 학습 내용을 하나의 Note에 합쳐 외부 링크로 공유했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://noteshare.space/note/cm4fip8g61475701mwwst60iuz#9vg7P01vzAvCcFbS/aeSC1T/QH9xtJoCr+lftxu0+gQ&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://noteshare.space/note/cm4fip8g61475701mwwst60iuz#9vg7P01vzAvCcFbS/aeSC1T/QH9xtJoCr+lftxu0+gQ&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1733657224593&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Noteshare.space &amp;mdash; Securely share your Obsidian notes with one click.&quot; data-og-description=&quot;Securely share your Obsidian notes with one click. Zero configuration. End-to-end encrypted. No account needed. Completely open source! Download the QuickShare extension in the Obsidian community plugin marketplace.&quot; data-og-host=&quot;noteshare.space&quot; data-og-source-url=&quot;https://noteshare.space/note/cm4fip8g61475701mwwst60iuz#9vg7P01vzAvCcFbS/aeSC1T/QH9xtJoCr+lftxu0+gQ&quot; data-og-url=&quot;https://noteshare.space/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bE0MsS/hyXGzdkqaY/mTL3H7jEYG85iJwwQdTSWk/img.png?width=1200&amp;amp;height=637&amp;amp;face=0_0_1200_637,https://scrap.kakaocdn.net/dn/brwUMh/hyXGLEKYsz/VpTlKr4qNEEyMLWZvsKNRK/img.png?width=1200&amp;amp;height=637&amp;amp;face=0_0_1200_637&quot;&gt;&lt;a href=&quot;https://noteshare.space/note/cm4fip8g61475701mwwst60iuz#9vg7P01vzAvCcFbS/aeSC1T/QH9xtJoCr+lftxu0+gQ&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://noteshare.space/note/cm4fip8g61475701mwwst60iuz#9vg7P01vzAvCcFbS/aeSC1T/QH9xtJoCr+lftxu0+gQ&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bE0MsS/hyXGzdkqaY/mTL3H7jEYG85iJwwQdTSWk/img.png?width=1200&amp;amp;height=637&amp;amp;face=0_0_1200_637,https://scrap.kakaocdn.net/dn/brwUMh/hyXGLEKYsz/VpTlKr4qNEEyMLWZvsKNRK/img.png?width=1200&amp;amp;height=637&amp;amp;face=0_0_1200_637');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Noteshare.space &amp;mdash; Securely share your Obsidian notes with one click.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Securely share your Obsidian notes with one click. Zero configuration. End-to-end encrypted. No account needed. Completely open source! Download the QuickShare extension in the Obsidian community plugin marketplace.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;noteshare.space&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Spring 관련 강의 수강&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인프런에서 김영한 강사님의 아래 두 강의를 수강했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;707&quot; data-origin-height=&quot;411&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QAL2P/btsLbbBXysI/uzeoEjOHTKNIugIwvAPyG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QAL2P/btsLbbBXysI/uzeoEjOHTKNIugIwvAPyG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QAL2P/btsLbbBXysI/uzeoEjOHTKNIugIwvAPyG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQAL2P%2FbtsLbbBXysI%2FuzeoEjOHTKNIugIwvAPyG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;554&quot; height=&quot;322&quot; data-origin-width=&quot;707&quot; data-origin-height=&quot;411&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;NextStep에서 진행한 '코드로 익히는 스프링 웹 프로그래밍' 교육 참여&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nJq4z/btsLbnbly1T/gkdk6IKX1xIXZu8vUrOx1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nJq4z/btsLbnbly1T/gkdk6IKX1xIXZu8vUrOx1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nJq4z/btsLbnbly1T/gkdk6IKX1xIXZu8vUrOx1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnJq4z%2FbtsLbnbly1T%2Fgkdk6IKX1xIXZu8vUrOx1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;452&quot; height=&quot;339&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;교육 내용은 비공개여서 GitHub private repository에 commit한 내역 캡처 사진을 첨부했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1128&quot; data-origin-height=&quot;781&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/W7hIB/btsLbv7Zb8a/uuSxKyxAAmhaKs0xEk67Z1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/W7hIB/btsLbv7Zb8a/uuSxKyxAAmhaKs0xEk67Z1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/W7hIB/btsLbv7Zb8a/uuSxKyxAAmhaKs0xEk67Z1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FW7hIB%2FbtsLbv7Zb8a%2FuuSxKyxAAmhaKs0xEk67Z1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;760&quot; height=&quot;526&quot; data-origin-width=&quot;1128&quot; data-origin-height=&quot;781&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1145&quot; data-origin-height=&quot;781&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEZ18I/btsLaZPlRkc/WMTVNy6uS9qneZdz3v0Z2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEZ18I/btsLaZPlRkc/WMTVNy6uS9qneZdz3v0Z2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEZ18I/btsLaZPlRkc/WMTVNy6uS9qneZdz3v0Z2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEZ18I%2FbtsLaZPlRkc%2FWMTVNy6uS9qneZdz3v0Z2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;759&quot; height=&quot;518&quot; data-origin-width=&quot;1145&quot; data-origin-height=&quot;781&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1148&quot; data-origin-height=&quot;294&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oFyrv/btsLbMPd3HH/CPSECidOzQEM4QF3JsWZm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oFyrv/btsLbMPd3HH/CPSECidOzQEM4QF3JsWZm1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oFyrv/btsLbMPd3HH/CPSECidOzQEM4QF3JsWZm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoFyrv%2FbtsLbMPd3HH%2FCPSECidOzQEM4QF3JsWZm1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;758&quot; height=&quot;294&quot; data-origin-width=&quot;1148&quot; data-origin-height=&quot;294&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS 자격증 공부&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS&amp;nbsp;자격증&amp;nbsp;관련&amp;nbsp;공부를&amp;nbsp;하면서&amp;nbsp;필기한&amp;nbsp;내용을&amp;nbsp;첨부합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;873&quot; data-origin-height=&quot;447&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dBWrRi/btsLcq50GKk/8JxxbW12jy3BVdKA1tOY40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dBWrRi/btsLcq50GKk/8JxxbW12jy3BVdKA1tOY40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dBWrRi/btsLcq50GKk/8JxxbW12jy3BVdKA1tOY40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdBWrRi%2FbtsLcq50GKk%2F8JxxbW12jy3BVdKA1tOY40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;447&quot; data-origin-width=&quot;873&quot; data-origin-height=&quot;447&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;481&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCXxCt/btsLbQKTfcG/wdUIswKROTTJPfwlxpVurk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCXxCt/btsLbQKTfcG/wdUIswKROTTJPfwlxpVurk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCXxCt/btsLbQKTfcG/wdUIswKROTTJPfwlxpVurk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCXxCt%2FbtsLbQKTfcG%2FwdUIswKROTTJPfwlxpVurk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;481&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;481&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;336&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AcNZ0/btsLbxxZ1E6/lbuDgPnGo7SkRxvvfy5SiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AcNZ0/btsLbxxZ1E6/lbuDgPnGo7SkRxvvfy5SiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AcNZ0/btsLbxxZ1E6/lbuDgPnGo7SkRxvvfy5SiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAcNZ0%2FbtsLbxxZ1E6%2FlbuDgPnGo7SkRxvvfy5SiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;669&quot; height=&quot;256&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;336&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <author>neveralone</author>
      <guid isPermaLink="true">https://iamneveralone.tistory.com/61</guid>
      <comments>https://iamneveralone.tistory.com/61#entry61comment</comments>
      <pubDate>Sun, 8 Dec 2024 21:05:08 +0900</pubDate>
    </item>
    <item>
      <title>[Spring Security] 공식 문서 파헤치기(1) - Architecture</title>
      <link>https://iamneveralone.tistory.com/60</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Spring Security 공식 문서 - Architecture&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.spring.io/spring-security/reference/servlet/architecture.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.spring.io/spring-security/reference/servlet/architecture.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1699111080374&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Architecture :: Spring Security&quot; data-og-description=&quot;The Security Filters are inserted into the FilterChainProxy with the SecurityFilterChain API. Those filters can be used for a number of different purposes, like authentication, authorization, exploit protection, and more. The filters are executed in a spec&quot; data-og-host=&quot;docs.spring.io&quot; data-og-source-url=&quot;https://docs.spring.io/spring-security/reference/servlet/architecture.html&quot; data-og-url=&quot;https://docs.spring.io/spring-security/reference/servlet/architecture.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bFqmAH/hyUnWQipKh/MyuK850gNhY3aACED1GUQ1/img.png?width=698&amp;amp;height=610&amp;amp;face=0_0_698_610,https://scrap.kakaocdn.net/dn/dUF7oj/hyUrv4yG9N/Ov9dRFWSqwtmi1k0bnIar0/img.png?width=740&amp;amp;height=507&amp;amp;face=0_0_740_507,https://scrap.kakaocdn.net/dn/bqkMOq/hyUnX2IbTy/d5K598wm2RhbfqVT1fJ6BK/img.png?width=686&amp;amp;height=508&amp;amp;face=0_0_686_508&quot;&gt;&lt;a href=&quot;https://docs.spring.io/spring-security/reference/servlet/architecture.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.spring.io/spring-security/reference/servlet/architecture.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bFqmAH/hyUnWQipKh/MyuK850gNhY3aACED1GUQ1/img.png?width=698&amp;amp;height=610&amp;amp;face=0_0_698_610,https://scrap.kakaocdn.net/dn/dUF7oj/hyUrv4yG9N/Ov9dRFWSqwtmi1k0bnIar0/img.png?width=740&amp;amp;height=507&amp;amp;face=0_0_740_507,https://scrap.kakaocdn.net/dn/bqkMOq/hyUnX2IbTy/d5K598wm2RhbfqVT1fJ6BK/img.png?width=686&amp;amp;height=508&amp;amp;face=0_0_686_508');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Architecture :: Spring Security&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The Security Filters are inserted into the FilterChainProxy with the SecurityFilterChain API. Those filters can be used for a number of different purposes, like authentication, authorization, exploit protection, and more. The filters are executed in a spec&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.spring.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Servlet Application&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Spring Security는 &lt;b&gt;표준 Servlet Filter&lt;/b&gt;를 사용하여 Servlet Container와 통합된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;즉, Servlet Container에서 실행되는 모든 application과 함께 동작한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;더 구체적으로 말하면, Spring Security의 이점을 활용하기 위해 Servlet-based application에서 Spring을 사용할 필요가 없다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Filter란?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;- HTTP 요청과 응답을 변경할 수 있는 재사용 가능한 코드&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 객체의 형태로 존재&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;b&gt;클라이언트로부터 오는 요청(Request)과 최종 자원 사이에 위치&lt;/b&gt;하여 클라이언트의 요청 정보를 알맞게 변경 가능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;b&gt;최종 자원과 클라이언트로 가능 응답(Response) 사이에 위치&lt;/b&gt;하여 최종 자원의 요청 결과를 알맞게 변경 가능&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;964&quot; data-origin-height=&quot;458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMVZlx/btszK9oihgr/q9ygIOmgCsWoG0HwBH8p90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMVZlx/btszK9oihgr/q9ygIOmgCsWoG0HwBH8p90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMVZlx/btszK9oihgr/q9ygIOmgCsWoG0HwBH8p90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMVZlx%2FbtszK9oihgr%2Fq9ygIOmgCsWoG0HwBH8p90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;490&quot; height=&quot;233&quot; data-origin-width=&quot;964&quot; data-origin-height=&quot;458&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 자원이 받게 되는 요청 정보는 &lt;b&gt;클라이언트와 자원 사이에 존재하는 필터&lt;/b&gt;에 의해 변경된 요청 정보가 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 클라이언트가 보게 되는 응답 정보는 &lt;b&gt;클라이언트와 자원 사이에 존재하는 필터&lt;/b&gt;에 의해 변경된 응답 정보가 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 필터는 클라이언트와 자원 사이에 1개만 존재하는 경우가 보통이지만, 여러 개의 필터가 모여서 하나의 체인(chain)을 형성할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;javax.servlet에 존재하는 Filter 인터페이스&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1699102702105&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface Filter {

    default void init(FilterConfig filterConfig) throws ServletException {
    }

    void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException;

    default void destroy() {
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Architecture&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;A Review of Filters&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Spring Security의 Servlet 지원은 Servlet Filter를 기반으로 하기 때문에&lt;/b&gt;, Filter의 역할을 먼저 알아두는 것이 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다음 이미지는 하나의(single) HTTP 요청에 대한 handler의 일반적인 layering을 보여준다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;462&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVCppX/btszHFIEGBV/NMNDAKPF3GZKAkP4PGlox0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVCppX/btszHFIEGBV/NMNDAKPF3GZKAkP4PGlox0/img.png&quot; data-alt=&quot;FilterChain&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVCppX/btszHFIEGBV/NMNDAKPF3GZKAkP4PGlox0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVCppX%2FbtszHFIEGBV%2FNMNDAKPF3GZKAkP4PGlox0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;258&quot; height=&quot;372&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;462&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;FilterChain&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;클라이언트는 application에 요청을 보내고, Container는 &lt;b&gt;요청 URI의 경로를 기반으로 HttpServletRequest를 처리&lt;/b&gt;해야 하는 Filter 인스턴스와 Servlet을 포함하는 &lt;b&gt;FilterChain&lt;/b&gt;을 생성한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Spring MVC application(응용 프로그램)에서 Servlet은 DispatcherServlet의 인스턴스이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;많아야 하나의 Servlet이 하나의 HttpServletRequest 및 HttpServletResponse를 처리할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하지만, 둘 이상의 Filter를 사용하여 다음 작업을 수행할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;b&gt;Downstream Filter 인스턴스 또는 Servlet이 호출되지 않도록 한다.&lt;/b&gt; &lt;b&gt;(무슨 말인지 모르겠다.)&lt;/b&gt; 이 경우 Filter는 일반적으로 HttpServletResponse를 쓴다(write).&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- Downstream Filter 인스턴스와 Servlet에서 사용하는 HttpServletRequest 또는 HttpServletResponse를 수정한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Filter의 힘은 FilterChain에서 나온다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;FilterChain Usage Example&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1699104092110&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    // do something before the rest of the application
    chain.doFilter(request, response); // invoke the rest of the application
    // do something after the rest of the application
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Filter는 downstream Filter 인스턴스와 Servlet에만 영향을 미치기 때문에, 각 Filter가 호출되는 순서가 매우 중요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(downstream이라는게 그 다음 순서를 의미하는 거 같기도 하다.)&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;DelegatingFilterProxy&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;: Servelt Filter를 구현한 Spring Bean에게 요청을 위임해주는 대리자 역할의 Servlet Filter&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;438&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yjWtY/btszLusduTJ/Ow30YLvxyxP95F1CEsZuCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yjWtY/btszLusduTJ/Ow30YLvxyxP95F1CEsZuCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yjWtY/btszLusduTJ/Ow30YLvxyxP95F1CEsZuCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyjWtY%2FbtszLusduTJ%2FOw30YLvxyxP95F1CEsZuCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;631&quot; height=&quot;138&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;438&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Spring은 &lt;b&gt;Servlet container의 라이프 사이클과 Spring의 ApplicationContext 사이의 연결(bridging)&lt;/b&gt;을 허용하는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;DelegatingFilterProxy라는 Filter 구현체&lt;/b&gt;&lt;/span&gt;를 제공한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Servlet Container는 자체 표준을 사용하여 Filter 인스턴스를 등록할 수 있지만, Spring이 정의한 Bean을 알지 못한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;표준 Servlet Container 메커니즘을 통해 DelegatingFilterProxy를 등록할 수 있지만 Filter를 구현하는 &lt;b&gt;Spring Bean에 모든 작업을 &lt;span style=&quot;color: #006dd7;&quot;&gt;위임(delegate)&lt;/span&gt;&lt;/b&gt;할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;41&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFtjAa/btszKJwANl6/5hm8gPnkNcfqRH4CFi8xQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFtjAa/btszKJwANl6/5hm8gPnkNcfqRH4CFi8xQK/img.png&quot; data-alt=&quot;DelegatingFilterProxy는 GenericFilterBean를 상속하고 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFtjAa/btszKJwANl6/5hm8gPnkNcfqRH4CFi8xQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFtjAa%2FbtszKJwANl6%2F5hm8gPnkNcfqRH4CFi8xQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;558&quot; height=&quot;36&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;41&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DelegatingFilterProxy는 GenericFilterBean를 상속하고 있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;68&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dlNTIX/btszHTNMh36/K0Kk7Jjwqfn3cfEWoqTY9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dlNTIX/btszHTNMh36/K0Kk7Jjwqfn3cfEWoqTY9k/img.png&quot; data-alt=&quot;GenericFilterBean 클래스는 Filter 인터페이스를 구현하고 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dlNTIX/btszHTNMh36/K0Kk7Jjwqfn3cfEWoqTY9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdlNTIX%2FbtszHTNMh36%2FK0Kk7Jjwqfn3cfEWoqTY9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;710&quot; height=&quot;52&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;68&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;GenericFilterBean 클래스는 Filter 인터페이스를 구현하고 있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;268&quot; data-origin-height=&quot;35&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjruQE/btszHFIE7sQ/yoqZMRV9gqgD3AYixRMRhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjruQE/btszHFIE7sQ/yoqZMRV9gqgD3AYixRMRhk/img.png&quot; data-alt=&quot;Filter 인터페이스 (javax.servlet)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjruQE/btszHFIE7sQ/yoqZMRV9gqgD3AYixRMRhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjruQE%2FbtszHFIE7sQ%2FyoqZMRV9gqgD3AYixRMRhk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;237&quot; height=&quot;31&quot; data-origin-width=&quot;268&quot; data-origin-height=&quot;35&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Filter 인터페이스 (javax.servlet)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다음은 DelegatingFilterProxy가 Filter 인스턴스들과 FilterChain에 어떻게 적용되어 있는지 보여주는 그림이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;508&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zw04J/btszLvkcnx6/UY3C8OYXM6uA8k7bzsFZh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zw04J/btszLvkcnx6/UY3C8OYXM6uA8k7bzsFZh0/img.png&quot; data-alt=&quot;DelegatingFilterProxy&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zw04J/btszLvkcnx6/UY3C8OYXM6uA8k7bzsFZh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fzw04J%2FbtszLvkcnx6%2FUY3C8OYXM6uA8k7bzsFZh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;280&quot; height=&quot;445&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;508&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DelegatingFilterProxy&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;DelegatingFilterProxy는 ApplicationContext에서 Bean Filter0을 찾은 다음 Bean Filter0을 호출한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다음은 DelegatingFilterProxy의 pseudo code를 보여준다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1699106161619&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
	Filter delegate = getFilterBean(someBeanName); // (1)
	delegate.doFilter(request, response); // (2)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(1) &lt;b&gt;Spring Bean으로 등록된 Filter를 lazy하게 가져온다.&lt;/b&gt; 위의 코드에서 delegate는 Bean Filter0의 인스턴스이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(2) 작업을 Spring Bean에게 위임한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;FilterProxy에 대한 모든 호출이 표준 Servlet Filter 인터페이스를 구현하는 데 필요한 Spring context의 해당 bean에 위임된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;DelegatingFilterProxy의 또 다른 장점은 Filter bean 인스턴스 조회를 지연시킬 수 있다는 점이다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이는 container가 시작하기 전에 Filter 인스턴스를 등록해야 하기 때문에 중요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러나, Spring은 일반적으로 ContextLoaderListener를 사용하여 Spring Bean을 등록(load)하는데, 이 작업은 Filter 인스턴스를 등록해야 할 때까지 수행되지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;FilterChainProxy&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Spring Security의 Servlet 지원은 FilterChainProxy 내에 포함되어 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;FilterChainProxy&lt;/b&gt;&lt;/span&gt;는 &lt;b&gt;SecurityFilterChain&lt;/b&gt;을 통해 많은 Filter 인스턴스들에게 위임할 수 있는 Spring Security에서 제공하는 특수한 Filter이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;FilterChainProxy는 Bean이기 때문에&lt;/span&gt; 일반적으로 DelegatingFilterProxy로 감싸진다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;36&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D6Xc1/btszOMFCKdd/Kd6LaKa5848biqnC7CmSw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D6Xc1/btszOMFCKdd/Kd6LaKa5848biqnC7CmSw0/img.png&quot; data-alt=&quot;FilterChainProxy 클래스는 GenericFilterBean 클래스를 상속하고 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D6Xc1/btszOMFCKdd/Kd6LaKa5848biqnC7CmSw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD6Xc1%2FbtszOMFCKdd%2FKd6LaKa5848biqnC7CmSw0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;541&quot; height=&quot;33&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;36&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;FilterChainProxy 클래스는 GenericFilterBean 클래스를 상속하고 있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;36&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/S2Axe/btszLoSXlTQ/Wn9IFJU75XOnIU3IRMSjHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/S2Axe/btszLoSXlTQ/Wn9IFJU75XOnIU3IRMSjHk/img.png&quot; data-alt=&quot;FilterChainProxy 내부의 필드 (SecurityFilterChain을 관리)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/S2Axe/btszLoSXlTQ/Wn9IFJU75XOnIU3IRMSjHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FS2Axe%2FbtszLoSXlTQ%2FWn9IFJU75XOnIU3IRMSjHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;421&quot; height=&quot;31&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;36&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;FilterChainProxy 내부의 필드 (SecurityFilterChain을 관리)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1033&quot; data-origin-height=&quot;174&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AhkW9/btszLangdi5/s8XazJvEDndoedyR4rooW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AhkW9/btszLangdi5/s8XazJvEDndoedyR4rooW1/img.png&quot; data-alt=&quot;SecurityFilterChain 한 개 또는 List를 인자로 받아 객체를 생성할 수 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AhkW9/btszLangdi5/s8XazJvEDndoedyR4rooW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAhkW9%2FbtszLangdi5%2Fs8XazJvEDndoedyR4rooW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;760&quot; height=&quot;128&quot; data-origin-width=&quot;1033&quot; data-origin-height=&quot;174&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SecurityFilterChain 한 개 또는 List를 인자로 받아 객체를 생성할 수 있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 이미지는 FilterChainProxy의 역할을 보여준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;508&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zyxPA/btszI2p89sX/wyeNxgvJYuUQHJjIMnhay1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zyxPA/btszI2p89sX/wyeNxgvJYuUQHJjIMnhay1/img.png&quot; data-alt=&quot;FilterChainProxy&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zyxPA/btszI2p89sX/wyeNxgvJYuUQHJjIMnhay1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzyxPA%2FbtszI2p89sX%2FwyeNxgvJYuUQHJjIMnhay1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;492&quot; height=&quot;381&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;508&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;FilterChainProxy&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;SecurityFilterChain&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;SecurityFilterChain&lt;/b&gt;&lt;/span&gt;은 FilterChainProxy에서 현재 요청에 대해 호출할 Spring Security의 Filter 인스턴스를 결정하는 데 사용된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;492&quot; data-origin-height=&quot;191&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y3VR8/btszKILdVri/Vo2hqAIi8KR0l1svwMUll0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y3VR8/btszKILdVri/Vo2hqAIi8KR0l1svwMUll0/img.png&quot; data-alt=&quot;SecurityFilterChain 인터페이스&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y3VR8/btszKILdVri/Vo2hqAIi8KR0l1svwMUll0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy3VR8%2FbtszKILdVri%2FVo2hqAIi8KR0l1svwMUll0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;374&quot; height=&quot;145&quot; data-origin-width=&quot;492&quot; data-origin-height=&quot;191&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SecurityFilterChain 인터페이스&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 이미지는 SecurityFilterChain의 역할을 보여준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;686&quot; data-origin-height=&quot;508&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MiDeS/btszONq0Dtk/kae3S6kIfc8oqIa5NeRAjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MiDeS/btszONq0Dtk/kae3S6kIfc8oqIa5NeRAjk/img.png&quot; data-alt=&quot;SecurityFilterChain&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MiDeS/btszONq0Dtk/kae3S6kIfc8oqIa5NeRAjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMiDeS%2FbtszONq0Dtk%2Fkae3S6kIfc8oqIa5NeRAjk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;508&quot; height=&quot;376&quot; data-origin-width=&quot;686&quot; data-origin-height=&quot;508&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SecurityFilterChain&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SecurityFilterChain의 Security Filter들은 일반적으로 Bean이지만, DelegatingFilterProxy가 아닌 FilterChainProxy에 등록되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;FilterChainProxy는 Servlet Container 또는 DelegatingFilterProxy에 직접 등록하는 데에 많은 이점을 제공한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2개의 이점은 너무 어려워서 공식 문서를 참고하자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;또한, SecurityFilterChain을 호출해야 하는 시기를 결정하는 데 더 많은 유연성을 제공한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Servlet Container에서 Filter 인스턴스는 URL에만 기반하여 호출되지만, FilterChainProxy는 RequestMatcher 인터페이스를 사용하여 HttpServletRequest에 있는 모든 것에 기반하여 호출을 결정할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다음 이미지는 여러 SecurityFilterChain 인스턴스를 보여준다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;548&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/miKND/btszHGHANl5/i3vdegwkixXaGfSHVxQwu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/miKND/btszHGHANl5/i3vdegwkixXaGfSHVxQwu1/img.png&quot; data-alt=&quot;Multiple SecurityFilterChain&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/miKND/btszHGHANl5/i3vdegwkixXaGfSHVxQwu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmiKND%2FbtszHGHANl5%2Fi3vdegwkixXaGfSHVxQwu1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;582&quot; height=&quot;405&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;548&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Multiple SecurityFilterChain&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위의 그림에서 FilterChainProxy는 어떤 SecurityFilterChain을 사용할지 결정한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;일치(match)하는 첫 번째 SecurityFilterChain만 호출된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;만약 &lt;b&gt;/api/messages/의 URL이 요청&lt;/b&gt;되면 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;먼저 SecurityFilterChain0 패턴의 /api/**와 일치하므로 SecurityFilterChain0만 호출된다.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;만약 &lt;b&gt;/messages/의 URL이 요청&lt;/b&gt;되면 /api/**의 SecurityFilterChain0 패턴과 일치하지 않으므로 &lt;b&gt;FilterChainProxy는 각 SecurityFilterChain을 계속해서 시도한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;일치하는 SecurityFilterChain 인스턴스가 없다고 가정하면, SecurityFilterChain n이 호출된다. (패턴이 /** 이기 때문)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SecurityFilterChain0은 3개의 Security Filter 인스턴스만 가지고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러나 SecurityFilterChain n은 4개의 Security Filter 인스턴스를 가지고 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;각 SecurityFilterChain은 고유(unique)할 수 있으며 분리되어 구성될 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실제로 application에서 Spring Security가 특정 요청을 무시하기를 원할 경우, SecurityFilterChain에는 0개의 Security Filter 인스턴스가 있을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Security Filters&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Security Filter들은 SecurityFilterChain API를 통해 FilterChainProxy에 삽입된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이러한 Filter들은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;인증(Authentication)&lt;/b&gt;&lt;/span&gt;, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;권한 부여(Authorization)&lt;/b&gt;&lt;/span&gt;, 악용 방지(Exploit protection) 등 여러 가지 목적으로 사용될 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Filter는 적절한 시기에 호출(invoke)되도록 보장하기 위해 특정 순서로 실행된다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예를 들어, 인증(authentication)을 수행하는 Filter는 권한 부여(authorization)를 수행하는 Filter보다 먼저 호출되어야 한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;일반적으로 Spring Security의 Filter 순서를 알 필요는 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다만, 순서를 아는 것이 유익할 때가 있는데 알고 싶다면 &lt;a href=&quot;https://github.com/spring-projects/spring-security/blob/6.1.5/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistration.java&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;FilterOrderRegistration 코드&lt;/a&gt;를 확인하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 문단을 예시로 들기 위해 다음과 같은 Security configuration을 고려해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1699114032894&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf(Customizer.withDefaults())
            .authorizeHttpRequests(authorize -&amp;gt; authorize
                .anyRequest().authenticated()
            )
            .httpBasic(Customizer.withDefaults())
            .formLogin(Customizer.withDefaults());
        return http.build();
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위의 설정 정보(configuration)는 다음과 같은 Filter 순서로 수행된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. 먼저, CSRF 공격으로부터 보호하기 위해 CsrfFilter가 호출된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 요청을 인증(authenticate)하기 위해 Authentication Filter들이 호출된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. AuthorizationFilter가 호출되어 요청을 승인한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 79.7675%; height: 190px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;b&gt;Filter&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;b&gt;Added by&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;a href=&quot;https://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;CsrfFilter&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;b&gt;HttpSecurity#csrf&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;a href=&quot;https://docs.spring.io/spring-security/reference/servlet/authentication/passwords/form.html#servlet-authentication-form&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;UsernamePasswordAuthenticationFilter&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;b&gt;HttpSecurity#formLogin&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;a href=&quot;https://docs.spring.io/spring-security/reference/servlet/authentication/passwords/basic.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;BasicAuthenticationFilter&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;b&gt;HttpSecurity#httpBasic&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;a href=&quot;https://docs.spring.io/spring-security/reference/servlet/authorization/authorize-http-requests.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;AuthorizationFilter&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;b&gt;HttpSecurity#authorizeHttpRequests&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;HttpSecurity 클래스&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/config/annotation/web/builders/HttpSecurity.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/config/annotation/web/builders/HttpSecurity.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1699115705793&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;HttpSecurity (Spring Security 4.0.4.RELEASE API)&quot; data-og-description=&quot;Allows specifying which HttpServletRequest instances this HttpSecurity will be invoked on. This method allows for easily invoking the HttpSecurity for multiple different RequestMatcher instances. If only a single RequestMatcher is necessary consider using &quot; data-og-host=&quot;docs.spring.io&quot; data-og-source-url=&quot;https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/config/annotation/web/builders/HttpSecurity.html&quot; data-og-url=&quot;https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/config/annotation/web/builders/HttpSecurity.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/config/annotation/web/builders/HttpSecurity.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/config/annotation/web/builders/HttpSecurity.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;HttpSecurity (Spring Security 4.0.4.RELEASE API)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Allows specifying which HttpServletRequest instances this HttpSecurity will be invoked on. This method allows for easily invoking the HttpSecurity for multiple different RequestMatcher instances. If only a single RequestMatcher is necessary consider using&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.spring.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;참고 블로그&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@vpdls1511/Servlet-%EC%9D%B4-%EB%AD%90%EA%B8%B8%EB%9E%98-Spring-%ED%95%A0-%EB%95%8C-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0%EA%B9%8C&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@vpdls1511/Servlet-%EC%9D%B4-%EB%AD%90%EA%B8%B8%EB%9E%98-Spring-%ED%95%A0-%EB%95%8C-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0%EA%B9%8C&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1699111017561&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Servlet 이 뭐길래 Spring 할 때 알아야 할까? - 1&quot; data-og-description=&quot;Spring Boot 에서 가장 중요한 개념 중 하나가 Servlet 이다. 왜 필요한지 알아보기 전, Servlet이 무엇인지부터 알아보자.&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@vpdls1511/Servlet-%EC%9D%B4-%EB%AD%90%EA%B8%B8%EB%9E%98-Spring-%ED%95%A0-%EB%95%8C-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0%EA%B9%8C&quot; data-og-url=&quot;https://velog.io/@vpdls1511/Servlet-이-뭐길래-Spring-할-때-알아야-할까&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/4vOxW/hyUrCP9F5s/Iuv9HOa2DCdiDakJPkLewk/img.png?width=850&amp;amp;height=450&amp;amp;face=123_158_246_293,https://scrap.kakaocdn.net/dn/c6htqb/hyUrCP9F6V/mDK9FeqSYiursDxBb0mmG0/img.png?width=850&amp;amp;height=450&amp;amp;face=123_158_246_293,https://scrap.kakaocdn.net/dn/bK2WrK/hyUrsGKB9E/RVuMkzBBYaEC7DPhBAhuK0/img.jpg?width=3024&amp;amp;height=3024&amp;amp;face=0_0_3024_3024&quot;&gt;&lt;a href=&quot;https://velog.io/@vpdls1511/Servlet-%EC%9D%B4-%EB%AD%90%EA%B8%B8%EB%9E%98-Spring-%ED%95%A0-%EB%95%8C-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0%EA%B9%8C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@vpdls1511/Servlet-%EC%9D%B4-%EB%AD%90%EA%B8%B8%EB%9E%98-Spring-%ED%95%A0-%EB%95%8C-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0%EA%B9%8C&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/4vOxW/hyUrCP9F5s/Iuv9HOa2DCdiDakJPkLewk/img.png?width=850&amp;amp;height=450&amp;amp;face=123_158_246_293,https://scrap.kakaocdn.net/dn/c6htqb/hyUrCP9F6V/mDK9FeqSYiursDxBb0mmG0/img.png?width=850&amp;amp;height=450&amp;amp;face=123_158_246_293,https://scrap.kakaocdn.net/dn/bK2WrK/hyUrsGKB9E/RVuMkzBBYaEC7DPhBAhuK0/img.jpg?width=3024&amp;amp;height=3024&amp;amp;face=0_0_3024_3024');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Servlet 이 뭐길래 Spring 할 때 알아야 할까? - 1&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot 에서 가장 중요한 개념 중 하나가 Servlet 이다. 왜 필요한지 알아보기 전, Servlet이 무엇인지부터 알아보자.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://toki0411.tistory.com/66&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://toki0411.tistory.com/66&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1699111058282&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[spring] 서블릿(Servlet)이란?&quot; data-og-description=&quot;목차 서블릿(Servlet)이란? 서블릿 컨테이너 JSP와 서블릿 1. 서블릿(Servlet)이란? 서블릿은 클라이언트의 요청을 처리하고, 그 결과를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍&quot; data-og-host=&quot;toki0411.tistory.com&quot; data-og-source-url=&quot;https://toki0411.tistory.com/66&quot; data-og-url=&quot;https://toki0411.tistory.com/66&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/zncHP/hyUrFe17AF/XCkC6yb0P16svIYwTKOB9K/img.png?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/vVfwI/hyUrDIihCi/zOK8pBQUaZPqyM8eZZZaUK/img.png?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/ci5eUj/hyUrw3tpzx/fkZDZwaUqkX9qqpzLaLCi1/img.png?width=1400&amp;amp;height=788&amp;amp;face=0_0_1400_788&quot;&gt;&lt;a href=&quot;https://toki0411.tistory.com/66&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://toki0411.tistory.com/66&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/zncHP/hyUrFe17AF/XCkC6yb0P16svIYwTKOB9K/img.png?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/vVfwI/hyUrDIihCi/zOK8pBQUaZPqyM8eZZZaUK/img.png?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/ci5eUj/hyUrw3tpzx/fkZDZwaUqkX9qqpzLaLCi1/img.png?width=1400&amp;amp;height=788&amp;amp;face=0_0_1400_788');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[spring] 서블릿(Servlet)이란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;목차 서블릿(Servlet)이란? 서블릿 컨테이너 JSP와 서블릿 1. 서블릿(Servlet)이란? 서블릿은 클라이언트의 요청을 처리하고, 그 결과를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;toki0411.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://catsbi.oopy.io/f9b0d83c-4775-47da-9c81-2261851fe0d0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://catsbi.oopy.io/f9b0d83c-4775-47da-9c81-2261851fe0d0&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1699114857997&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;스프링 시큐리티 주요 아키텍처 이해&quot; data-og-description=&quot;목차&quot; data-og-host=&quot;catsbi.oopy.io&quot; data-og-source-url=&quot;https://catsbi.oopy.io/f9b0d83c-4775-47da-9c81-2261851fe0d0&quot; data-og-url=&quot;https://catsbi.oopy.io/f9b0d83c-4775-47da-9c81-2261851fe0d0&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/k3Xjb/hyUnSf3nQn/nw6WOL6QL9YUHhRxONJsu0/img.png?width=2000&amp;amp;height=438&amp;amp;face=0_0_2000_438,https://scrap.kakaocdn.net/dn/0ZpVv/hyUnOEITAQ/KPrX2oRVVVdoEBnrnhHa40/img.png?width=2000&amp;amp;height=438&amp;amp;face=0_0_2000_438,https://scrap.kakaocdn.net/dn/iS56v/hyUnTsve0a/ZBDBSn806HpFXzkJPPnRkk/img.png?width=2000&amp;amp;height=1034&amp;amp;face=0_0_2000_1034&quot;&gt;&lt;a href=&quot;https://catsbi.oopy.io/f9b0d83c-4775-47da-9c81-2261851fe0d0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://catsbi.oopy.io/f9b0d83c-4775-47da-9c81-2261851fe0d0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/k3Xjb/hyUnSf3nQn/nw6WOL6QL9YUHhRxONJsu0/img.png?width=2000&amp;amp;height=438&amp;amp;face=0_0_2000_438,https://scrap.kakaocdn.net/dn/0ZpVv/hyUnOEITAQ/KPrX2oRVVVdoEBnrnhHa40/img.png?width=2000&amp;amp;height=438&amp;amp;face=0_0_2000_438,https://scrap.kakaocdn.net/dn/iS56v/hyUnTsve0a/ZBDBSn806HpFXzkJPPnRkk/img.png?width=2000&amp;amp;height=1034&amp;amp;face=0_0_2000_1034');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;스프링 시큐리티 주요 아키텍처 이해&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;catsbi.oopy.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>Spring Security</category>
      <author>neveralone</author>
      <guid isPermaLink="true">https://iamneveralone.tistory.com/60</guid>
      <comments>https://iamneveralone.tistory.com/60#entry60comment</comments>
      <pubDate>Sun, 5 Nov 2023 01:21:17 +0900</pubDate>
    </item>
    <item>
      <title>[백준 1504] 특정한 최단 경로 (C++) - G4</title>
      <link>https://iamneveralone.tistory.com/58</link>
      <description>&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://www.acmicpc.net/problem/1504&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/1504&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695965752296&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;1504번: 특정한 최단 경로&quot; data-og-description=&quot;첫째 줄에 정점의 개수 N과 간선의 개수 E가 주어진다. (2 &amp;le; N &amp;le; 800, 0 &amp;le; E &amp;le; 200,000) 둘째 줄부터 E개의 줄에 걸쳐서 세 개의 정수 a, b, c가 주어지는데, a번 정점에서 b번 정점까지 양방향 길이 존&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/1504&quot; data-og-url=&quot;https://www.acmicpc.net/problem/1504&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Bj3RN/hyT2FHsYxD/sL3QkwSQ4LE0CCriZQiEy1/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1504&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/1504&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Bj3RN/hyT2FHsYxD/sL3QkwSQ4LE0CCriZQiEy1/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;1504번: 특정한 최단 경로&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 정점의 개수 N과 간선의 개수 E가 주어진다. (2 &amp;le; N &amp;le; 800, 0 &amp;le; E &amp;le; 200,000) 둘째 줄부터 E개의 줄에 걸쳐서 세 개의 정수 a, b, c가 주어지는데, a번 정점에서 b번 정점까지 양방향 길이 존&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;개요&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;어제 &lt;span style=&quot;text-align: start;&quot;&gt;블로그에&lt;/span&gt; 다익스트라(Dijkstra) 알고리즘을 정리한 글을 작성했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고, 오늘 실제로 다익스트라를 활용한 문제를 풀어보고자 이 문제를 풀어보았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예전에는 다익스트라 코드를 무식하게 다 외우기만 해서 시간이 지나면 금방 휘발되었는데, 확실히 알고리즘 동작 과정을 세세하게 이해하면서 코드를 직접 작성하니까 실수 없이 다익스트라 코드를 작성할 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;또한, 이 문제는 다익스트라 코드만 알면 조금만 응용해서 금방 풀 수 있는 쉬운 문제였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제 풀이&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제에서 &lt;b&gt;&quot;1번 정점에서 N번 정점으로 최단 거리로 이동하려고 한다.&quot;&lt;/b&gt;를 보고 &lt;b&gt;최단 경로 알고리즘&lt;/b&gt;을 사용해야 함을 바로 떠올렸다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;또한, 입력으로 주어지는 정점 사이의 거리 &lt;b&gt;c의 범위가 &lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt;&lt;b&gt;1 &amp;le; c &amp;le; 1,000&lt;/b&gt;이므로, 음수가 될 수 없기 때문에 &lt;b&gt;다익스트라 알고리즘&lt;/b&gt;을 사용해야함을 알 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다만, 1번 정점에서 시작하여 두 정점 v1, v2를 반드시 거치면서 N번 정점까지 도달해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;즉, 다음과 같은 2가지 경우가 존재한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1) 1 &amp;rarr; v1 &amp;rarr; v2 &amp;rarr; N&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2) 1 &amp;rarr; v2 &amp;rarr; v1 &amp;rarr; N&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;가장 기본적인 다익스트라 문제처럼 dijkstra(1)만 작성하면 1번 정점으로부터 각 정점까지의 최소 거리밖에 알 수 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;첫번째 경우만 보더라도, 우리는 1번 정점에서 v1 정점까지의 최소 거리뿐만 아니라, &lt;b&gt;v1 정점으로부터 v2 정점까지의 최소 거리&lt;/b&gt;도 알아야 하고, &lt;b&gt;v2 정점에서 N번 정점까지의 최소 거리&lt;/b&gt;도 알아야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;즉, 다익스트라를 한 번만 실행해서는 안 되고, 시작점을 v1, v2로 하는 다익스트라를 추가적으로 실행해주어야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;dijkstra(1)&lt;/b&gt;을 통해 1 &amp;rarr; v1, 1 &amp;rarr; v2 최소 거리를 알 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;dijkstra(v1)&lt;/b&gt;을 통해 v1 &amp;rarr; v2, v1&amp;nbsp; &amp;rarr; N 최소 거리를 알 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(방향 없는 그래프이므로 v1 &amp;rarr; v2 최소 거리와 v2 &amp;rarr; v1 최소 거리는 같다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;dijkstra(v2)&lt;/b&gt;을 통해 v2 &lt;b&gt;&amp;rarr;&lt;/b&gt; N 최소 거리를 알 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;즉, 3번의 다익스트라를 실행하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;주의할 점은 다음 다익스트라 실행 전에 fill 함수를 통해 dist 배열의 모든 값을 다시 INF로 초기화해주어야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코드&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1695965923630&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstring&amp;gt;
#include &amp;lt;sstream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;deque&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;map&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;bitset&amp;gt;
#include &amp;lt;cmath&amp;gt;

#define INF (~0U &amp;gt;&amp;gt; 2) // 약 10억 7천만 (1073741823)

using namespace std;
using pii = pair&amp;lt;int, int&amp;gt;;

vector&amp;lt;pii&amp;gt; adj[801];
vector&amp;lt;int&amp;gt; dist(801, INF);

void dijkstra(int start) {
	dist[start] = 0;
	priority_queue &amp;lt;pii, vector&amp;lt;pii&amp;gt;, greater&amp;lt;&amp;gt;&amp;gt; pq;
	pq.push({ dist[start], start });

	while (!pq.empty()) {

		int cur_dist = pq.top().first; // 현재 정점까지의 최소 거리
		int cur = pq.top().second;
		pq.pop();

		if (dist[cur] &amp;lt; cur_dist) continue;

		for (auto k : adj[cur]) {

			int next_dist = k.first; // 현재 정점에서 다음 정점까지의 거리
			int next = k.second;

			if (cur_dist + next_dist &amp;lt; dist[next]) {
				dist[next] = cur_dist + next_dist;
				pq.push({ dist[next], next });
			}

		}
	}
}

int main(void) {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	int n, e; cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; e;
	for (int i = 0; i &amp;lt; e; i++) {
		int a, b, c; cin &amp;gt;&amp;gt; a &amp;gt;&amp;gt; b &amp;gt;&amp;gt; c;
		adj[a].push_back({ c, b });
		adj[b].push_back({ c, a });
	}
	int v1, v2; cin &amp;gt;&amp;gt; v1 &amp;gt;&amp;gt; v2;
	
	// 1 -&amp;gt; v1 -&amp;gt; v2 -&amp;gt; n
	// 1 -&amp;gt; v2 -&amp;gt; v1 -&amp;gt; n

	dijkstra(1);
	int s_to_v1 = dist[v1]; // 1 -&amp;gt; v1
	int s_to_v2 = dist[v2]; // 1 -&amp;gt; v2
	fill(dist.begin(), dist.end(), INF);

	dijkstra(v1);
	int v1_to_v2 = dist[v2]; // v1 -&amp;gt; v2 &amp;lt;=&amp;gt; v2 -&amp;gt; v1
	int v1_to_n = dist[n]; // v1 -&amp;gt; n
	fill(dist.begin(), dist.end(), INF);

	dijkstra(v2);
	int v2_to_n = dist[n];

	int sum1 = s_to_v1 + v1_to_v2 + v2_to_n;
	int sum2 = s_to_v2 + v1_to_v2 + v1_to_n;
	int ans = min(sum1, sum2);
	
	if (ans &amp;gt;= INF) cout &amp;lt;&amp;lt; -1;
	else cout &amp;lt;&amp;lt; ans;
	
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;깨달은 점&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다익스트라 알고리즘을 이용한 문제를 풀어보았는데, 난이도는 Gold IV이지만, 코드를 확실히 이해하고 나니까 그렇게 어렵게 느껴지지 않았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;빠른 시일 내에 벨만-포드 알고리즘과 플로이드-와샬 알고리즘도 블로그에 글을 작성하며 공부해야겠다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>백준 문제 리뷰/그래프</category>
      <author>neveralone</author>
      <guid isPermaLink="true">https://iamneveralone.tistory.com/58</guid>
      <comments>https://iamneveralone.tistory.com/58#entry58comment</comments>
      <pubDate>Fri, 29 Sep 2023 14:51:27 +0900</pubDate>
    </item>
    <item>
      <title>[알고리즘] 다익스트라(Dijkstra)</title>
      <link>https://iamneveralone.tistory.com/57</link>
      <description>&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;최단 경로(Shortest Path) 알고리즘&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;다익스트라(Dijkstra)&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;b&gt;벨만-포드(Bellman-Ford)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;b&gt;플로이드-와샬(Floyd-Warshall)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다익스트라(Dijkstra) 알고리즘이란?&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다익스트라 알고리즘은&amp;nbsp;&lt;b&gt;최단경로(Shortest Path) 알고리즘&lt;/b&gt;&amp;nbsp;중의 하나입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;더 정확히는, &lt;b&gt;그래프의 한 정점에서 다른 정점들까지의 최단 거리를 구하는 알고리즘&lt;/b&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다만, 가중치의 값이 음수인 간선이 존재하는 경우에는 다익스트라 알고리즘을 사용할 수 없습니다. (이 경우에는 벨만-포드 알고리즘을 사용해야 합니다.)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;즉, &lt;b&gt;다익스트라 알고리즘은 간선의 가중치가 모두 0 또는 양수인 경우에만 사용 가능합니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다익스트라 알고리즘의 로직은 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;1. 출발 정점을 설정한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;2. 출발 정점와 인접해있는 정점들까지의 거리를 갱신한다.&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;3. 아직 방문하지 않은 정점들 중 기록된 거리가 가장 짧은 정점 u를 하나 선택하여 방문한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;(u를 선택할 때, 꼭 현재 정점과 인접한 정점이 아니어도 상관 없다. 멀리 떨어져있는 정점이라도 dist 값이 가장 작은 정점을 선택한다.)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;4. 해당 정점 u와 인접하고 아직 방문하지 않은 정점들까지의 거리를 갱신한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; (해당 정점을 거쳐서 방문할 수 있는 정점까지의 거리가 이전에 기록된 값보다 작다면 그 거리를 갱신한다.)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;5. 3과 4를 반복한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예시를 통해 그 과정을 더 자세히 살펴보도록 하자.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다음과 같은 그래프가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;584&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eoa33V/btswbdUJ0g1/46M78wYpsus5SRsFpIi6m1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eoa33V/btswbdUJ0g1/46M78wYpsus5SRsFpIi6m1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eoa33V/btswbdUJ0g1/46M78wYpsus5SRsFpIi6m1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Feoa33V%2FbtswbdUJ0g1%2F46M78wYpsus5SRsFpIi6m1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;284&quot; height=&quot;254&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;584&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시작 정점은 0번이라고 가정하자.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고, 일차원 배열 dist에 각 정점까지의 최단거리를 저장할 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;처음에는 각 정점까지의 거리를 모두 INF로 초기화한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 79.4186%; height: 34px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center; height: 17px;&quot;&gt;&lt;b&gt;Vertex&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center; height: 17px;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center; height: 17px;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center; height: 17px;&quot;&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center; height: 17px;&quot;&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center; height: 17px;&quot;&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center; height: 17px;&quot;&gt;&lt;b&gt;5&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center; height: 17px;&quot;&gt;&lt;b&gt;Cost&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center; height: 17px;&quot;&gt;&lt;b&gt;INF&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center; height: 17px;&quot;&gt;&lt;b&gt;INF&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center; height: 17px;&quot;&gt;&lt;b&gt;INF&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center; height: 17px;&quot;&gt;&lt;b&gt;INF&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center; height: 17px;&quot;&gt;&lt;b&gt;INF&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center; height: 17px;&quot;&gt;&lt;b&gt;INF&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;678&quot; data-origin-height=&quot;594&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWPXx7/btsv7lGoriD/SmL1MjqsEoyoWQDx5YWiMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWPXx7/btsv7lGoriD/SmL1MjqsEoyoWQDx5YWiMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWPXx7/btsv7lGoriD/SmL1MjqsEoyoWQDx5YWiMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWPXx7%2Fbtsv7lGoriD%2FSmL1MjqsEoyoWQDx5YWiMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;284&quot; height=&quot;249&quot; data-origin-width=&quot;678&quot; data-origin-height=&quot;594&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 79.4186%; height: 34px;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;Vertex&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;5&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;Cost&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;INF&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;INF&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;INF&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;INF&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;INF&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; - 시작 정점인 0을 방문한다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 시작 정점인 0에 대한 dist 배열 값을 0으로 설정한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWTQHk/btswarS7Cmy/RBeJ5kjzB2OzglSVpd1Dik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWTQHk/btswarS7Cmy/RBeJ5kjzB2OzglSVpd1Dik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWTQHk/btswarS7Cmy/RBeJ5kjzB2OzglSVpd1Dik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWTQHk%2FbtswarS7Cmy%2FRBeJ5kjzB2OzglSVpd1Dik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;292&quot; height=&quot;251&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 79.4186%; height: 34px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;Vertex&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;5&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;Cost&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;7&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;9&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;INF&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;INF&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;14&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 0번 정점과 인접하면서 아직 방문하지 않은 정점인 1, 2, 5번 정점까지의 거리를 갱신한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;rarr; &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;0번 정점을 거쳐서 k번 정점으로 가는 거리인 dist[0] + cost[0][k]가 dist[k]보다 작으면 갱신한다.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 아직 방문하지 않은 정점 중 거리(dist 배열 값)가 가장 짧은 1번 정점을 방문한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;659&quot; data-origin-height=&quot;579&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zhQ4o/btsv7Acqllz/KkG72opP7FDvkrqoDOmcy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zhQ4o/btsv7Acqllz/KkG72opP7FDvkrqoDOmcy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zhQ4o/btsv7Acqllz/KkG72opP7FDvkrqoDOmcy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzhQ4o%2Fbtsv7Acqllz%2FKkG72opP7FDvkrqoDOmcy1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;264&quot; data-origin-width=&quot;659&quot; data-origin-height=&quot;579&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 79.4186%; height: 34px;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;Vertex&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;5&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;Cost&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;7&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;9&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;22&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;INF&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;14&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt; - 1번 정점과 인접하면서 아직 방문하지 않은 정점인 2, 3번 정점까지의 거리를 갱신한다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp; &lt;span style=&quot;text-align: start;&quot;&gt;&amp;rarr; &lt;b&gt;1번 정점을 거쳐서 k번 정점으로 가는 거리인 dist[1] + cost[1][k]가 dist[k]보다 작으면 갱신한다.&lt;/b&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;사실, &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: start;&quot;&gt;dist[1] + cost[1][2] = 17 &amp;gt; 9 = dist[2] 이므로 2번 정점까지의 거리(dist[2])는 갱신하지 않는다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;- &lt;b&gt;즉, 3번 정점까지의 거리(dist[3])만 갱신한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;- 그리고, &lt;span style=&quot;text-align: start;&quot;&gt;아직 방문하지 않은 정점 중 거리(dist 배열 값)가 가장 짧은 2번 정점을 방문한다.&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;570&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DjAcL/btsv8Pz4vTV/cgtVrSsr6WfuRdZz2Jkcp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DjAcL/btsv8Pz4vTV/cgtVrSsr6WfuRdZz2Jkcp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DjAcL/btsv8Pz4vTV/cgtVrSsr6WfuRdZz2Jkcp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDjAcL%2Fbtsv8Pz4vTV%2FcgtVrSsr6WfuRdZz2Jkcp0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;313&quot; height=&quot;267&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;570&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 79.4186%; height: 34px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;Vertex&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;5&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;Cost&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;7&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;9&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;20&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;INF&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;11&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;- 2번 정점과 인접하면서 아직 방문하지 않은 정점인 3, 5번 정점까지의 거리를 갱신한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;rarr;&lt;b&gt; 2번 정점을 거쳐서 k번 정점으로 가는 거리인 dist[2] + cost[2][k]가 dist[k]보다 작으면 갱신한다.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;- &lt;/span&gt;&lt;span style=&quot;text-align: start; color: #000000;&quot;&gt;아직 방문하지 않은 정점 중 거리(dist 배열 값)가 가장 짧은 5번 정점을 방문한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;581&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fzofv/btswbd1vBi7/kk8XHcIPIFDgWwpKgHuZl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fzofv/btswbd1vBi7/kk8XHcIPIFDgWwpKgHuZl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fzofv/btswbd1vBi7/kk8XHcIPIFDgWwpKgHuZl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFzofv%2Fbtswbd1vBi7%2Fkk8XHcIPIFDgWwpKgHuZl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;313&quot; height=&quot;278&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;581&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 79.4186%; height: 34px;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;Vertex&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;5&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;Cost&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;7&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;9&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;20&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;20&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;11&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;- 5번 정점과 인접하면서 아직 방문하지 않은 정점인 4번 정점까지의 거리를 갱신한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;rarr;&lt;b&gt; 5번 정점을 거쳐서 k번 정점으로 가는 거리인 dist[5] + cost[5][k]가 dist[k]보다 작으면 갱신한다.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;text-align: start; color: #000000;&quot;&gt;아직 방문하지 않은 정점 중 거리(dist 배열 값)가 가장 짧은 3번 정점을 방문한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: start; color: #000000;&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;rarr; &lt;b&gt;dist[3]과 dist[4]의 값이 20으로 동일하기 때문에 둘 중 아무 정점이나 방문해도 상관 없다.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: start; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;rarr; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;꼭 5번 정점과 인접한 4번 정점을 방문할 필요는 없다. 3번 정점을 방문해도 상관 없다.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;581&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/F7gAj/btsv7yTcYMV/5JxdCp9awc6iEcqXVPX00k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/F7gAj/btsv7yTcYMV/5JxdCp9awc6iEcqXVPX00k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/F7gAj/btsv7yTcYMV/5JxdCp9awc6iEcqXVPX00k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FF7gAj%2Fbtsv7yTcYMV%2F5JxdCp9awc6iEcqXVPX00k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;314&quot; height=&quot;279&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;581&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 79.4186%; height: 34px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;Vertex&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;5&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;Cost&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;7&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;9&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;20&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;20&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;11&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;- 3번 정점과 인접하면서 아직 방문하지 않은 정점인 4번 정점까지의 거리를 갱신한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;rarr;&lt;b&gt; 3번 정점을 거쳐서 k번 정점으로 가는 거리인 dist[3] + cost[3][k]가 dist[k]보다 작으면 갱신한다.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;span style=&quot;text-align: start;&quot;&gt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;사실,&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: start;&quot;&gt;dist[3] + cost[3][4] = 26 &amp;gt; 20 = dist[4] 이므로 4번 정점까지의 거리(dist[4])는 갱신하지 않는다.&lt;/span&gt; &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: start; color: #000000;&quot;&gt;- 즉, 어떤 값도 갱신하지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;text-align: start; color: #000000;&quot;&gt;아직 방문하지 않은 정점 중 거리(dist 배열 값)가 가장 짧은 4번 정점을 방문한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;584&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdo5Xx/btsv0pbtf77/UgWpPMMpsCkmbVD1DmuKUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdo5Xx/btsv0pbtf77/UgWpPMMpsCkmbVD1DmuKUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdo5Xx/btsv0pbtf77/UgWpPMMpsCkmbVD1DmuKUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbdo5Xx%2Fbtsv0pbtf77%2FUgWpPMMpsCkmbVD1DmuKUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;303&quot; height=&quot;276&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;584&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 79.4186%; height: 34px;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;Vertex&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;5&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;Cost&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;7&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;9&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;20&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;20&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;11&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 정점을 방문했기 때문에 아무 것도 하지 않고 마무리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;다익스트라(Dijkstra) 알고리즘 코드 (C++)&lt;/h3&gt;
&lt;pre id=&quot;code_1695886727736&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstring&amp;gt;
#include &amp;lt;sstream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;deque&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;map&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;bitset&amp;gt;
#include &amp;lt;cmath&amp;gt;

#define INF (~0U &amp;gt;&amp;gt; 2) // 약 10억 7천만 (1073741823)

using namespace std;

int v, e, k; // 정점 개수, 간선 개수, 시작 정점
vector&amp;lt;pair&amp;lt;int, int&amp;gt;&amp;gt; adj[20001]; // 인접 리스트 (인접한 정점과 그 정점까지의 거리를 저장)
vector&amp;lt;int&amp;gt; dist(20001, INF);


// 우선순위 큐
// 큰 원소부터 pop : priority_queue&amp;lt;int&amp;gt; pq;
// 작은 원소부터 pop : priority_queue&amp;lt;int, vector&amp;lt;int&amp;gt;, greater&amp;lt;int&amp;gt;&amp;gt; pq;

void dijkstra(int start) { // start는 시작 정점
	dist[start] = 0;

	priority_queue&amp;lt;pair&amp;lt;int, int&amp;gt;, vector&amp;lt;pair&amp;lt;int, int&amp;gt;&amp;gt;, greater&amp;lt;&amp;gt;&amp;gt; pq; // ({dist[k], k} 저장)
	pq.push({ dist[k], k });

	while (!pq.empty()) {
		int cur_dist = pq.top().first;
		int cur = pq.top().second;
		pq.pop();

		// 이미 방문한 정점은 무시 (이미 방문한 정점의 dist 값은 가장 최소인 상태)
		if (dist[cur] &amp;lt; cur_dist) continue;

		for (auto k : adj[cur]) {
			int next_dist = k.first;
			int next = k.second;

			// 현재 정점을 거쳐서 인접 정점을 방문하는 것이 더 거리가 짧은 경우
			// &amp;lt;=&amp;gt; dist[cur] + adj[cur][next] &amp;lt; dist[next]
			if (cur_dist + next_dist &amp;lt; dist[next]) { 
				// 거리 갱신
				dist[next] = cur_dist + next_dist;
				pq.push({ dist[next], next });
			}
		}
	}
}

int main(void) {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	cin &amp;gt;&amp;gt; v &amp;gt;&amp;gt; e &amp;gt;&amp;gt; k;

	for (int i = 0; i &amp;lt; e; i++) {
		int a, b, c; cin &amp;gt;&amp;gt; a &amp;gt;&amp;gt; b &amp;gt;&amp;gt; c;
		adj[a].push_back({ c, b });
	}

	dijkstra(k);

	for (int i = 1; i &amp;lt;= v; i++) {
		if (dist[i] == INF) cout &amp;lt;&amp;lt; &quot;INF\n&quot;;
		else cout &amp;lt;&amp;lt; dist[i] &amp;lt;&amp;lt; '\n';
	}

	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위 코드는 백준 1753번 [최단 경로] 문제의 해답 코드이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://www.acmicpc.net/problem/1753&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/1753&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695886837375&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;1753번: 최단경로&quot; data-og-description=&quot;첫째 줄에 정점의 개수 V와 간선의 개수 E가 주어진다. (1 &amp;le; V &amp;le; 20,000, 1 &amp;le; E &amp;le; 300,000) 모든 정점에는 1부터 V까지 번호가 매겨져 있다고 가정한다. 둘째 줄에는 시작 정점의 번호 K(1 &amp;le; K &amp;le; V)가 &quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/1753&quot; data-og-url=&quot;https://www.acmicpc.net/problem/1753&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cCU4VY/hyT2vkkKic/qFrziRgCwT7ErZyIsf51RK/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1753&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/1753&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cCU4VY/hyT2vkkKic/qFrziRgCwT7ErZyIsf51RK/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;1753번: 최단경로&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 정점의 개수 V와 간선의 개수 E가 주어진다. (1 &amp;le; V &amp;le; 20,000, 1 &amp;le; E &amp;le; 300,000) 모든 정점에는 1부터 V까지 번호가 매겨져 있다고 가정한다. 둘째 줄에는 시작 정점의 번호 K(1 &amp;le; K &amp;le; V)가&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;주의할 점&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;[주의점 1]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;priority_queue의 원소로 pair&amp;lt;int, int&amp;gt;를 사용할 때 따로 비교 함수를 지정해주지 않는다면 first를 기준으로 정렬된다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다익스트라 알고리즘에서는 priority_queue에서 정점 k에 대한 dist[k] 값이 여러 번 갱신된다면 priority_queue에 {dist[k], k} 쌍이 여러 개 존재할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그 여러 쌍 중에서, dist[k] 값이 작은 것이 더 앞으로 가도록 하기 때문에, &lt;b&gt;정렬 기준이 되는 dist 값을 first 위치에 두어야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695887073106&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pq.push({ dist[next], next });&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고, dist[k] 값이 가장 작은 {dist[k], k} 쌍이 선택되어 정점 k에 방문하면, 말 그대로 dist[k] 값은 가능한 가장 최소의 값을 가지고 있는 상태이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그런데, priority_queue에 이제는 필요없는 {dist[k], k} 쌍들이 남아있을 수 있기 때문에, 이 쌍들을 무시하기 위해 다음과 같은 코드를 작성해주어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695955753073&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if (dist[cur] &amp;lt; cur_dist) continue;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;[주의점 2]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;vector에서 큰 원소부터 접근하기 위해서는 &lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;내림차순 정렬 sort(v.begin(), v.end(), greater&amp;lt;&amp;gt;())&lt;/span&gt;을 하고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;작은 원소부터 접근하기 위해서는 &lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;오름차순 정렬 sort(v.begin(), v.end())&lt;/span&gt;을 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;비슷한 방식으로, &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;우선순위 큐에서 큰 원소부터 pop하기 위해서는 &lt;b&gt;priority_queue&amp;lt;int&amp;gt; pq를&lt;/b&gt;&amp;nbsp;하고,&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;작은 원소부터 pop하기 위해서는 &lt;b&gt;priority_queue&amp;lt;int, vector&amp;lt;int&amp;gt;, greater&amp;lt;int&amp;gt;&amp;gt; pq를&lt;/b&gt;&amp;nbsp;한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다음과 같이 이해하면 쉽게 기억할 수 있을 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;vector는기존 그대로 생각하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;b&gt;sort(v.begin(), v.end())&lt;/b&gt;를 하면 맨 앞에서부터, 즉 가장 작은 원소부터 접근하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wWSJm/btsv7VOd4wN/0dkkkAhs8JXSjuUoncxWK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wWSJm/btsv7VOd4wN/0dkkkAhs8JXSjuUoncxWK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wWSJm/btsv7VOd4wN/0dkkkAhs8JXSjuUoncxWK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwWSJm%2Fbtsv7VOd4wN%2F0dkkkAhs8JXSjuUoncxWK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;254&quot; height=&quot;60&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;priority_queue는 vector를 세로로 세워서 생각하면 편하다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;그리고 맨 위에서부터 원소에 접근한다고 생각하면 된다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;145&quot; data-origin-height=&quot;520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsSv7V/btsv9OA47am/adCXYL7120KmSMCcsGPmj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsSv7V/btsv9OA47am/adCXYL7120KmSMCcsGPmj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsSv7V/btsv9OA47am/adCXYL7120KmSMCcsGPmj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsSv7V%2Fbtsv9OA47am%2FadCXYL7120KmSMCcsGPmj0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;65&quot; height=&quot;233&quot; data-origin-width=&quot;145&quot; data-origin-height=&quot;520&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;즉, &lt;b&gt;priority_queue&amp;lt;int&amp;gt; pq&lt;/b&gt;를 사용하면 우선 순위 큐에서 가장 큰 수부터 pop할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;즉, vector와 priority_queue는 반대로 접근하면 된다.&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>알고리즘 정리</category>
      <author>neveralone</author>
      <guid isPermaLink="true">https://iamneveralone.tistory.com/57</guid>
      <comments>https://iamneveralone.tistory.com/57#entry57comment</comments>
      <pubDate>Thu, 28 Sep 2023 17:03:04 +0900</pubDate>
    </item>
    <item>
      <title>[백준 14500] 테트로미노 (C++) - G4</title>
      <link>https://iamneveralone.tistory.com/56</link>
      <description>&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://www.acmicpc.net/problem/14500&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/14500&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695791977052&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;14500번: 테트로미노&quot; data-og-description=&quot;폴리오미노란 크기가 1&amp;times;1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/14500&quot; data-og-url=&quot;https://www.acmicpc.net/problem/14500&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c8zBXX/hyT2sANDX7/TEsmkA3FrQ8bZ9FLLIaOsK/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480,https://scrap.kakaocdn.net/dn/b7qtrA/hyT2romOAb/KChB5MbrNc6HR9PalUgkY1/img.png?width=500&amp;amp;height=333&amp;amp;face=0_0_500_333&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14500&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/14500&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c8zBXX/hyT2sANDX7/TEsmkA3FrQ8bZ9FLLIaOsK/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480,https://scrap.kakaocdn.net/dn/b7qtrA/hyT2romOAb/KChB5MbrNc6HR9PalUgkY1/img.png?width=500&amp;amp;height=333&amp;amp;face=0_0_500_333');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;14500번: 테트로미노&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;폴리오미노란 크기가 1&amp;times;1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 문제는 &lt;b&gt;구현&lt;/b&gt; 문제이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;324&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b16NUy/btsv7nXl7wE/9TNGXMkqq6fuOrQ0gcs3X1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b16NUy/btsv7nXl7wE/9TNGXMkqq6fuOrQ0gcs3X1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b16NUy/btsv7nXl7wE/9TNGXMkqq6fuOrQ0gcs3X1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb16NUy%2Fbtsv7nXl7wE%2F9TNGXMkqq6fuOrQ0gcs3X1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;248&quot; height=&quot;169&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;324&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위의 5가지 종류의 테트로미노가 주어지는데, 회전과 대칭이 가능하기 때문에 가능한 모양은 5개가 아니라 사실상 총 19개가 나온다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;19가지 경우를 모두 하나하나 구현해야하는 것인가 하고 굉장히 막막했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러던 중에 &lt;b&gt;DFS + 백트래킹&lt;/b&gt;을 이용하면 더욱 쉽게 풀 수 있음을 알게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제 풀이&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위에서 언급했던 총 19가지 모양에 대해 각각 if문을 구현하여 총 19개의 if문을 포함하는 함수를 구현할 수도 있을 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러나, 이와 같은 방법은 중간에 실수할 가능성도 크고 중간에 코드를 잘못 적었으면 찾기도 힘들 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 문제는 &lt;b&gt;DFS + 백트래킹&lt;/b&gt;을 이용하여 더 간단하게 풀 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;왜 DFS를 사용할 수 있는 것일까?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다음 그림을 보자.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1317&quot; data-origin-height=&quot;892&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZyhRC/btsv8fY4r46/owSkAKUI6kMKS5KgnAdHOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZyhRC/btsv8fY4r46/owSkAKUI6kMKS5KgnAdHOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZyhRC/btsv8fY4r46/owSkAKUI6kMKS5KgnAdHOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZyhRC%2Fbtsv8fY4r46%2FowSkAKUI6kMKS5KgnAdHOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;347&quot; height=&quot;235&quot; data-origin-width=&quot;1317&quot; data-origin-height=&quot;892&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5가지 모양 중에 'ㅜ' 모양을 제외한 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;나머지 4개의 모양은 Depth가 3인 도형&lt;/b&gt;&lt;/span&gt;임을 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;즉, 다음과 같이 &lt;b&gt;한 좌표에 대해서 Depth가 3인 DFS를 실행하면, 해당 좌표를 기준으로 한 4개의 모양(회전, 대칭 포함)에 대한 합을 각각 구할 수 있다. &lt;/b&gt;(아래 그림에서 검은 동그라미가 기준 좌표이다.)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;994&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOQfIf/btsv8fSjJTp/qVqczpGXaI0r5ci7dXlls1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOQfIf/btsv8fSjJTp/qVqczpGXaI0r5ci7dXlls1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOQfIf/btsv8fSjJTp/qVqczpGXaI0r5ci7dXlls1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOQfIf%2Fbtsv8fSjJTp%2FqVqczpGXaI0r5ci7dXlls1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;265&quot; height=&quot;266&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;994&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;DFS&lt;/b&gt;&lt;/span&gt;를 통해 Depth = 3까지 타고 들어가서 지나온 좌표에 저장된 숫자의 합을 구하는 방식으로 진행한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여기서 중요한 점은, &lt;b&gt;한 좌표에 대해서 Depth = 3으로 타고 들어가는 방법은 여러 경우가 있기 때문에 &lt;span style=&quot;color: #006dd7;&quot;&gt;백트래킹(Backtracking)&lt;/span&gt;을 사용&lt;/b&gt;하여 &lt;b&gt;여러 경우에서의 숫자의 합을 모두 구하면서 최종적으로 가장 큰 합을 구해야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 &lt;b&gt;'ㅜ' 모양에 대해서는 DFS를 사용하여 구할 수 없기 때문에 따로 if문을 통해 구현해주어야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;321&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwGQEG/btsvXU27XCd/TO6WiShbzeZGnXm4BIKR00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwGQEG/btsvXU27XCd/TO6WiShbzeZGnXm4BIKR00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwGQEG/btsvXU27XCd/TO6WiShbzeZGnXm4BIKR00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwGQEG%2FbtsvXU27XCd%2FTO6WiShbzeZGnXm4BIKR00%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;556&quot; height=&quot;148&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;321&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(그림에서 검은 동그라미는 기준이 되는 좌표이다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위의 4가지 모양에 대해서 if문을 구현하여 총 4개의 if문을 가진 ohshape 함수를 따로 작성해주었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코드&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1695792252760&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstring&amp;gt;
#include &amp;lt;sstream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;deque&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;map&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;bitset&amp;gt;
#include &amp;lt;cmath&amp;gt;

#define INF (~0U &amp;gt;&amp;gt; 2) // 약 10억 7천만 (1073741823)

using namespace std;

int n, m, ans;
int arr[500][500];
int visited[500][500];
int dy[4] = { 1, 0, -1, 0 };
int dx[4] = { 0, 1, 0, -1 };

// ㅗ 모양 따로 처리 (대칭, 회전 고려)
void ohshape(int y, int x) {

	// ㅜ
	if (y + 1 &amp;lt; n &amp;amp;&amp;amp; x + 2 &amp;lt; m)
		ans = max(ans, arr[y][x] + arr[y][x + 1] + arr[y][x + 2] + arr[y + 1][x + 1]);
	// ㅏ
	if (y + 2 &amp;lt; n &amp;amp;&amp;amp; x + 1 &amp;lt; m)
		ans = max(ans, arr[y][x] + arr[y + 1][x] + arr[y + 2][x] + arr[y + 1][x + 1]);
	// ㅗ
	if (y - 1 &amp;gt;= 0 &amp;amp;&amp;amp; x + 2 &amp;lt; m)
		ans = max(ans, arr[y][x] + arr[y][x + 1] + arr[y][x + 2] + arr[y - 1][x + 1]);
	// ㅓ
	if (y + 2 &amp;lt; n &amp;amp;&amp;amp; x - 1 &amp;gt;= 0)
		ans = max(ans, arr[y][x] + arr[y + 1][x] + arr[y + 2][x] + arr[y + 1][x - 1]);
}

// DFS + Backtracking
void dfs(int y, int x, int sum, int depth) {

	if (depth == 3) {
		ans = max(ans, sum);
		return;
	}

	for (int i = 0; i &amp;lt; 4; i++) {
		int ny = y + dy[i];
		int nx = x + dx[i];

		if (ny &amp;lt; 0 || nx &amp;lt; 0 || ny &amp;gt;= n || nx &amp;gt;= m) continue;

		if (visited[ny][nx] == 0) {
			visited[ny][nx] = 1;
			dfs(ny, nx, sum + arr[ny][nx], depth + 1);
			visited[ny][nx] = 0;
		}
	}
}

int main(void) {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; m;
	for (int i = 0; i &amp;lt; n; i++) {
		for (int j = 0; j &amp;lt; m; j++) {
			cin &amp;gt;&amp;gt; arr[i][j];
		}
	}

	for (int i = 0; i &amp;lt; n; i++) {
		for (int j = 0; j &amp;lt; m; j++) {
			ohshape(i, j);
			visited[i][j] = 1;
			dfs(i, j, arr[i][j], 0);
			visited[i][j] = 0;
		}
	}

	cout &amp;lt;&amp;lt; ans;
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;깨달은 점&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구현 문제는 무식하게 모든 경우를 일일이 나눠서 코드를 작성해야 하는 줄 알았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러나, 이 문제와 같이 구현 문제에서도 DFS + 백트래킹을 사용하면 코드가 훨씬 간결해지는 것을 알게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구현 문제를 풀 때, 문제 설명을 읽은 후에 해당 문제가 DFS 또는 백트래킹을 사용하여 접근할 수 있는지를 얼마나 빨리 판단하는지가 중요할 것 같다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>백준 문제 리뷰/삼성 SW 기출</category>
      <author>neveralone</author>
      <guid isPermaLink="true">https://iamneveralone.tistory.com/56</guid>
      <comments>https://iamneveralone.tistory.com/56#entry56comment</comments>
      <pubDate>Wed, 27 Sep 2023 14:46:40 +0900</pubDate>
    </item>
    <item>
      <title>[백준 14503] 로봇 청소기 (C++) - G5</title>
      <link>https://iamneveralone.tistory.com/55</link>
      <description>&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://www.acmicpc.net/problem/14503&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/14503&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695743112222&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;14503번: 로봇 청소기&quot; data-og-description=&quot;첫째 줄에 방의 크기 $N$과 $M$이 입력된다. $(3 \le N, M \le 50)$  둘째 줄에 처음에 로봇 청소기가 있는 칸의 좌표 $(r, c)$와 처음에 로봇 청소기가 바라보는 방향 $d$가 입력된다. $d$가 $0$인 경우 북쪽&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/14503&quot; data-og-url=&quot;https://www.acmicpc.net/problem/14503&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/vyszd/hyT2yt7pGy/FRKJk56cOkZJKgZrqp5dkK/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14503&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/14503&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/vyszd/hyT2yt7pGy/FRKJk56cOkZJKgZrqp5dkK/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;14503번: 로봇 청소기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 방의 크기 $N$과 $M$이 입력된다. $(3 \le N, M \le 50)$  둘째 줄에 처음에 로봇 청소기가 있는 칸의 좌표 $(r, c)$와 처음에 로봇 청소기가 바라보는 방향 $d$가 입력된다. $d$가 $0$인 경우 북쪽&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;개요&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;처음 풀어본 시뮬레이션 문제이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;일단 직접 그림을 그려보지 않고 머릿속으로만 생각하다보니까 문제 설명을 이해하는 데 굉장히 오래 걸렸다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고, 시뮬레이션 문제라는 사실에 미리 겁을 먹은 것도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시뮬레이션 문제는 뭔가 특별한 방식을 사용하는 줄 알고 DFS, BFS를 사용하면 안 될 것 같다는 착각에 빠졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그래서 굉장히 이상한 함수 구현에 힘을 들였고, 결국 이 문제 또한 구글링의 힘을 빌렸다...&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제 설명에 대한 이해는 직접 태블릿으로 그림을 그려보니까 쉽게 이해할 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다음은 문제에 주어진 예제 2와 그에 대한 풀이 그림이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;664&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bU7wDE/btsvNrUMNhs/hYUeMLXih8NXtpk6LVny80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bU7wDE/btsvNrUMNhs/hYUeMLXih8NXtpk6LVny80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bU7wDE/btsvNrUMNhs/hYUeMLXih8NXtpk6LVny80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbU7wDE%2FbtsvNrUMNhs%2FhYUeMLXih8NXtpk6LVny80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;503&quot; height=&quot;398&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;664&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1165&quot; data-origin-height=&quot;1242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JUNbY/btsvXRYSv0P/PqEo76ePetGFEKeLKQ1nLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JUNbY/btsvXRYSv0P/PqEo76ePetGFEKeLKQ1nLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JUNbY/btsvXRYSv0P/PqEo76ePetGFEKeLKQ1nLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJUNbY%2FbtsvXRYSv0P%2FPqEo76ePetGFEKeLKQ1nLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;360&quot; height=&quot;384&quot; data-origin-width=&quot;1165&quot; data-origin-height=&quot;1242&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제 풀이&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 문제는 BFS로 풀 수도 있고, DFS로 풀 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사실 문제 풀이에 장황하게 글로 쓸 내용은 많지 않고, 코드를 따라가다 보면 쉽게 이해할 수 있을 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;BFS 코드에서 중요한 부분을 2군데만 꼽자면 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;첫번째 부분은 다음 코드이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695744045853&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int dy[4] = { -1, 0, 1, 0 };
int dx[4] = { 0, 1, 0, -1 }; // 순서 : 북(0), 동(1), 남(2), 서(3)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1695744080311&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for (int i = 0; i &amp;lt; 4; i++) {
	int nd = (cd + (3 - i)) % 4; // 시계 반대 방향 회전 (0 -&amp;gt; 3 -&amp;gt; 2 -&amp;gt; 1)
	int ny = cy + dy[nd];
	int nx = cx + dx[nd];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위 코드는 사실 기존의 BFS 코드에 등장하는 코드와 크게 다르지 않다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다른 점은 이 문제에는 방향에 대한 개념이 존재한다는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;방향은 4가지 방향이 존재하고, 시계 반대 방향으로 회전하면서 현재 바라보는 방향을 바꾼다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제에 따르면, 0은 북쪽, 1은 동쪽, 2는 남쪽, 3은 서쪽을 의미한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;따라서, &lt;b&gt;시계 반대 방향으로 회전함에 따라, 0 &amp;rarr; 3 &amp;rarr; 2 &amp;rarr; 1 &amp;rarr; 0 이런 식으로 회전&lt;/b&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;위의 내용을 바탕으로 nd를 구하는 식을 작성한 것이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;일단 방향이 4개 단위로 반복되며 회전하기 때문에 nd를 구하는 식의 마지막에는 4로 나눠주는 % 4 부분이 있을 것이라는 사실은 예상할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;따라서, nd = (cd + x) % 4 이런 형태가 될 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이제 우리는 x에 해당하는 식만 구하면 되는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예를 들어, &lt;b&gt;현재 cd = 0&lt;/b&gt;이라고 해보자. 즉, 현재 바라보는 방향이 북쪽인 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;i = 0&lt;/b&gt;이면, 시계 반대 방향으로 90도 한 번 회전한 것이기 때문에 nd = 3(서쪽)이 나와야 하므로,&lt;b&gt; x = 3&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;i = 1&lt;/b&gt;이면, 시계 반대 방향으로 90도 한 번 더 회전한 것이기 때문에 nd = 2(남쪽)가 나와야 하므로,&lt;b&gt; x = 2&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;b&gt;i = 2&lt;/b&gt;&lt;span style=&quot;text-align: start;&quot;&gt;이면, 시계 반대 방향으로 90도 한 번 더 회전한 것이기 때문에&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;nd = 1(동쪽)이 나와야 하므로, &lt;b&gt;x = 1&lt;/b&gt;이다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;b&gt;i = 3&lt;/b&gt;&lt;span style=&quot;text-align: start;&quot;&gt;이면, 시계 반대 방향으로 90도 한 번 더 회전한 것이기 때문에&amp;nbsp;&lt;/span&gt;nd = 0(북쪽)이 나와야 하므로,&lt;b&gt; x = 0&lt;/b&gt;이다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;즉, 위의 4가지 경우로부터 &lt;b&gt;x = 3 - i&lt;/b&gt; 임을 알 수 있고, &lt;b&gt;결론적으로 nd = (cd + (3 - i)) % 4 라는 식을 얻을 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;두번째 부분은 다음 코드이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695744143053&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 네 방향 모두 청소되어 있는 경우
if (!flag) { 

	// 현재 바라보고 있는 방향 유지한 채로 한 칸 후진
	int by = cy - dy[cd];
	int bx = cx - dx[cd]; 

	if (by &amp;lt; 0 || bx &amp;lt; 0 || by &amp;gt;= n || bx &amp;gt;= m) continue;

	// 후진한 위치가 벽이 아니면
	if (arr[by][bx] != 1) {
		q.push({ {by, bx}, cd });
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위 코드는 &lt;b&gt;현재 위치에서 네 방향 모두 청소되어 있는 경우&lt;/b&gt;에 대한 코드이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;현재 바라보고 있는 방향(cd)를 유지한 채로 한 칸 후진&lt;/b&gt;한 위치 (by, bx)를 구한 후에, 그 위치가 벽이 아니라면, 즉 arr[by][bx]가 1이 아니라면 현재 바라보는 방향 cd와 함께 queue에 push해준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코드&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;BFS 풀이&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695743814180&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstring&amp;gt;
#include &amp;lt;sstream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;deque&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;map&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;bitset&amp;gt;
#include &amp;lt;cmath&amp;gt;

#define INF (~0U &amp;gt;&amp;gt; 2) // 약 10억 7천만 (1073741823)

using namespace std;

int n, m, ans;
int arr[50][50];
int dy[4] = { -1, 0, 1, 0 };
int dx[4] = { 0, 1, 0, -1 }; // 순서 : 북(0), 동(1), 남(2), 서(3)

void bfs(int y, int x, int d) {
	
	queue &amp;lt;pair&amp;lt;pair&amp;lt;int, int&amp;gt;, int&amp;gt;&amp;gt; q;
	q.push({ {y, x}, d });
	
	while (!q.empty()) {
		int cy = q.front().first.first;
		int cx = q.front().first.second;
		int cd = q.front().second; // 현재 바라보고 있는 방향
		
		if (arr[cy][cx] == 0) {
			arr[cy][cx] = 2; // 청소 완료
			ans++;
		}
		q.pop();

		bool flag = false; // true : 네 방향 중에 청소되지 않은 빈 칸 있음
		for (int i = 0; i &amp;lt; 4; i++) {
			int nd = (cd + (3 - i)) % 4; // 시계 반대 방향 회전 (0 -&amp;gt; 3 -&amp;gt; 2 -&amp;gt; 1)
			int ny = cy + dy[nd];
			int nx = cx + dx[nd];

			if (ny &amp;lt; 0 || nx &amp;lt; 0 || ny &amp;gt;= n || nx &amp;gt;= m) continue;

			if (arr[ny][nx] == 0) {
				q.push({ {ny, nx}, nd });
				flag = true;
				break;
			}
		}

		// 네 방향 모두 청소되어 있는 경우
		if (!flag) { 

			// 현재 바라보고 있는 방향 유지한 채로 한 칸 후진
			int by = cy - dy[cd];
			int bx = cx - dx[cd]; 

			if (by &amp;lt; 0 || bx &amp;lt; 0 || by &amp;gt;= n || bx &amp;gt;= m) continue;

			// 후진한 위치가 벽이 아니면
			if (arr[by][bx] != 1) {
				q.push({ {by, bx}, cd });
			}
		}
	}
}

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

	cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; m;
	int y, x, d; cin &amp;gt;&amp;gt; y &amp;gt;&amp;gt; x &amp;gt;&amp;gt; d;
	for (int i = 0; i &amp;lt; n; i++) {
		for (int j = 0; j &amp;lt; m; j++) {
			cin &amp;gt;&amp;gt; arr[i][j];
		}
	}
	bfs(y, x, d);
	cout &amp;lt;&amp;lt; ans;
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;DFS 풀이&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695743842064&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstring&amp;gt;
#include &amp;lt;sstream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;deque&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;map&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;bitset&amp;gt;
#include &amp;lt;cmath&amp;gt;

#define INF (~0U &amp;gt;&amp;gt; 2) // 약 10억 7천만 (1073741823)

using namespace std;

int n, m, ans;
int arr[50][50];

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

void dfs(int cy, int cx, int cd) {
	
	if (arr[cy][cx] == 0) {
		arr[cy][cx] = 2;
		ans++;
	}

	for (int i = 0; i &amp;lt; 4; i++) {
		int nd = (cd + (3 - i)) % 4;
		int ny = cy + dy[nd];
		int nx = cx + dx[nd];

		if (nx &amp;lt; 0 || ny &amp;lt; 0 || ny &amp;gt;= n || nx &amp;gt;= m) {
			continue;
		}

		if (arr[ny][nx] == 0) {
			dfs(ny, nx, nd);
		}
	}

	int by = cy - dy[cd];
	int bx = cx - dx[cd];

	if (arr[by][bx] == 1) {
		cout &amp;lt;&amp;lt; ans;
		exit(0);
	}
	dfs(by, bx, cd); // 현재 바라보는 방향을 유지한 채 후진
}


int main(void) {
	cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; m;

	int y, x, d;
	cin &amp;gt;&amp;gt; y &amp;gt;&amp;gt; x &amp;gt;&amp;gt; d;

	for (int i = 0; i &amp;lt; n; i++) {
		for (int j = 0; j &amp;lt; m; j++) {
			cin &amp;gt;&amp;gt; arr[i][j];
		}
	}

	dfs(y, x, d);

	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;깨달은 점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시뮬레이션 문제라고 해서 뭔가 크게 다른 유형이 아니고, 오히려 DFS, BFS를 더 잘 다룰 줄 알아야 한다는 것을 깨닫게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>백준 문제 리뷰/삼성 SW 기출</category>
      <author>neveralone</author>
      <guid isPermaLink="true">https://iamneveralone.tistory.com/55</guid>
      <comments>https://iamneveralone.tistory.com/55#entry55comment</comments>
      <pubDate>Wed, 27 Sep 2023 01:19:48 +0900</pubDate>
    </item>
    <item>
      <title>[백준 15686] 치킨 배달 (C++) - G5</title>
      <link>https://iamneveralone.tistory.com/54</link>
      <description>&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/15686&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/15686&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695524104056&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;15686번: 치킨 배달&quot; data-og-description=&quot;크기가 N&amp;times;N인 도시가 있다. 도시는 1&amp;times;1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/15686&quot; data-og-url=&quot;https://www.acmicpc.net/problem/15686&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/OFSuA/hyTY4AQSeW/2rzUTJ32RwRxNplCml5Pk1/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/15686&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/15686&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/OFSuA/hyTY4AQSeW/2rzUTJ32RwRxNplCml5Pk1/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;15686번: 치킨 배달&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;크기가 N&amp;times;N인 도시가 있다. 도시는 1&amp;times;1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;개요&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제를 처음 봤을 때 백트래킹 문제임을 바로 파악하지는 못했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이차원 배열이 주어져서 당연하게 DFS 혹은 BFS로 접근해야겠다고 생각했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;백트래킹을 고려하지 않고 있었기 때문에, 여러 개의 치킨집 중에서 M개를 어떻게 선택해야 할지 고민하는 데에 시간을 굉장히 많이 썼다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 문제 또한 결국 구글링의 힘을 빌렸다...! (언제쯤 혼자 풀어낼 거냐..나 자신아..)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;백트래킹 문제를 연속으로 풀면서, &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;여러 가지 경우의 수 중에서 M개를 선택해야 하는 문제 유형&lt;/span&gt;은 백트래킹 가능성이 굉장히 높다&lt;/b&gt;는 것을 인지하게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;문제 풀이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 문제 또한 전형적인 백트래킹 문제이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;답을 구하는 로직은 굉장히 간단하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;여러 개의 치킨집 중에서 M개를 선택한 후, 각각의 집에 대해서 M개의 치킨집까지의 거리 중 가장 최소의 거리를 더한 것이 최종 결과값이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위의 로직에서, 여러 개의 치킨집 중에서 M개를 선택하는 과정이 곧 백트래킹을 사용해야 함을 나타내고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;일단, pair&amp;lt;int, int&amp;gt; 타입으로 house, chicken, picked 3개의 vector를 전역변수로 선언해주었다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;house는 집(1)의 좌표, chicken은 치킨집(2)의 좌표, picked는 치킨집들 중에서 M개에 선택된 치킨집의 좌표를 저장하는 역할이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고, 이차원 배열을 입력받는 과정에서, 1인 경우는 house에, 2인 경우는 chicken에 저장해주었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(굳이 이차원 배열을 선언해서 모든 값을 저장할 필요가 없다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고, 백트래킹을 위한 함수 func를 선언해준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;여태까지 백트래킹 문제를 풀어본 바로는, 백트래킹 함수 func는 거의 항상 다음과 같은 형태를 갖는다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;1. 인자로 idx, cnt를 포함한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp;(idx : &lt;b&gt;배열 또는 벡터에서 원소를 탐색하는 포인터 역할 / cnt : 여러 경우의 수 중에서 문제 조건으로 주어진 특정 횟수까지 카운팅하는 용도, 탈출조건에 사용됨)&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;2. if문을 이용한 탈출 조건 + return&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;3. func 함수를 재귀적으로 타고 들어가는 부분 + 앞뒤로 방문 여부 true/false 전환 + vector 원소 push_back/pop_back&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;일단 func 함수를 재귀적으로 타고 들어가는 부분을 먼저 구현한 다음에, 탈출 조건 부분을 구현하는 것이 더 편한 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;func 함수를 재귀적으로 타고 들어가는 부분&lt;/b&gt;은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695533425280&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for (int i = idx; i &amp;lt; chicken.size(); i++) {
	if (check[i]) continue;
		
	check[i] = true;
	picked.push_back(chicken[i]); // 치킨집 중에서 선택
	func(i, cnt + 1);
	check[i] = false;
	picked.pop_back();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;위의 for문에서 가장 중요한 점은 for문의 시작값에 idx를 사용한다는 것이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;애초에 idx는 이 용도를 위해 사용되는 인자이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;for문 내의 func 함수에 현재 i를 넘겨줌으로써, 타고 들어간 func 함수에서는 이 i가 idx 역할을 하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그래서 &lt;b&gt;굳이 매번 i = 0부터 탐색할 필요 없이 이전 마지막 위치부터 확인함으로써 효율성을 높이는 것&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;idx를 사용하지 않고, i = 0부터 탐색하게 되면 시간 초과가 뜰 가능성이 높다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;탈출 조건 부분&lt;/b&gt;은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695533716951&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if (cnt == m) { // 탈출 조건
	int sum = 0; // 하나의 경우의 최종 결과 (중간 정답)
	for (int i = 0; i &amp;lt; house.size(); i++) { // 모든 집에 대해서 min_dist 구함
		int min_dist = INF;
		for (int j = 0; j &amp;lt; picked.size(); j++) { // 선택된 M개의 치킨집들에 대해 최소 거리를 구함
			min_dist = min(min_dist, distance(house[i], picked[j]));
		}
		sum += min_dist;
	}
	ans = min(ans, sum); // 중간 정답인 sum인 최종 정답인 ans와의 비교를 거쳐야 함
	return;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 문제는 특히 까다로웠던 것이, min 함수를 2번이나 사용해야 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;각각의 집에 대해서 M개의 치킨집까지의 거리 중에서 &lt;b&gt;최소 거리&lt;/b&gt;를 구하는 과정에서 &lt;b&gt;min을 한 번 사용&lt;/b&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고, 각 집의 최소 거리를 더한 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;중간 정답 sum&lt;/b&gt;&lt;/span&gt;을 구한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그런데, 이 경우는 여러 개의 치킨집 중에서 M개를 선택하는 경우의 수 중에 하나의 경우일 뿐이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;M개를 선택하는 나머지 경우에 대해서도 똑같은 과정을 진행하게 될 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;모든 경우를 다 진행한 후에 도출되는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;최종 정답이 ans&lt;/b&gt;&lt;/span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그래서, &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;각 경우에 대해 중간 정답 sum과 최종 정답 ans를 비교하는 과정이 필요&lt;/b&gt;&lt;/span&gt;하고, 이 때 &lt;b&gt;min을 한 번 더 사용&lt;/b&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고, &lt;b&gt;min을 사용하는 경우에는 사용될 변수를 처음에 엄청 큰 값으로 설정해놓아야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;일반적으로, #define을 통해 INF라는 변수에 이 큰 값을 설정해놓는다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1695534451623&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#define INF (~0U &amp;gt;&amp;gt; 2) // 약 10억 7천만 (1073741823)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;나는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;(~0U &amp;gt;&amp;gt; 2)&lt;/b&gt;&lt;/span&gt;를 사용하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;0U는 unsigned int 0을 의미하고, ~는 NOT을 의미한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;0U는 32개의 0으로 이루어져 있고, ~에 의해 32개의 1로 뒤집힌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 shift 연산자 &amp;gt;&amp;gt;와 숫자 2에 의해 비트를 오른쪽으로 2번 shift함으로써, 앞의 두 비트는 0이고, 나머지 30개의 비트는 1으로 이루어진 32비트짜리 숫자가 되는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;즉, 2^0부터 2^29까지 모두 더한 값이므로, &lt;b&gt;2^30 - 1 = 1073741823, 약 10억 7천만의 값을 가진 숫자이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;이 숫자의 좋은 점은 INF + INF를 해도 2^31 - 2이어서 int의 최대 범위인 2^31 - 1보다 빈틈없게 작다는 점이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 이 숫자가 기억나지 않을 때에는 &lt;b&gt;통상적으로 사용하는 987654321&lt;/b&gt;를 사용해도 큰 상관은 없을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코드&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1695524156519&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstring&amp;gt;
#include &amp;lt;sstream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;deque&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;map&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;bitset&amp;gt;
#include &amp;lt;cmath&amp;gt;

#define INF (~0U &amp;gt;&amp;gt; 2) // 약 10억 7천만 (1073741823)

using namespace std;

int n, m;
int ans = INF; // 최종 정답
vector&amp;lt;pair&amp;lt;int, int&amp;gt;&amp;gt; house; // 집 좌표
vector&amp;lt;pair&amp;lt;int, int&amp;gt;&amp;gt; chicken; // 치킨집 좌표
vector&amp;lt;pair&amp;lt;int, int&amp;gt;&amp;gt; picked; // M개에 선택받은 치킨집 좌표
bool check[13]; // check 배열의 인덱스는 chicken 배열의 인덱스와 매칭


int distance(pair&amp;lt;int, int&amp;gt; a, pair&amp;lt;int, int&amp;gt; b) {
	return abs(a.first - b.first) + abs(a.second - b.second);
}

void func(int idx, int cnt) { // idx : 
	if (cnt == m) { // 탈출 조건
		int sum = 0; // 하나의 경우의 최종 결과 (중간 정답)
		for (int i = 0; i &amp;lt; house.size(); i++) { // 모든 집에 대해서 min_dist 구함
			int min_dist = INF;
			for (int j = 0; j &amp;lt; picked.size(); j++) { // 선택된 M개의 치킨집들에 대해 최소 거리를 구함
				min_dist = min(min_dist, distance(house[i], picked[j]));
			}
			sum += min_dist;
		}
		ans = min(ans, sum); // 중간 정답인 sum인 최종 정답인 ans와의 비교를 거쳐야 함
		return;
	}
	for (int i = idx; i &amp;lt; chicken.size(); i++) {
		if (check[i]) continue;
		
		check[i] = true;
		picked.push_back(chicken[i]); // 치킨집 중에서 선택
		func(i, cnt + 1);
		check[i] = false;
		picked.pop_back();
	}
}

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

	cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; m;
	for (int i = 0; i &amp;lt; n; i++) {
		for (int j = 0; j &amp;lt; n; j++) {
			int num; cin &amp;gt;&amp;gt; num;
			if (num == 1) house.push_back({ i, j });
			if (num == 2) chicken.push_back({ i, j });
		}
	}
	dfs(0, 0);
	cout &amp;lt;&amp;lt; ans;
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;깨달은 점&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;백트래킹 문제를 연속으로 풀면서 공통적으로 발견되는 패턴이 있음을 인지할 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;또한, 탈출 조건을 구현할 때에 생각보다 그 내용이 길어지는 경우가 많은데 이 부분을 따로 함수로 빼서 구현할지 아니면 원래대로 if문 안에 다 구현하는게 나을지는 비슷한 유형을 많이 풀어보면서 나한테 더 편하고 직관적인 방식을 선택해야겠다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>백준 문제 리뷰/삼성 SW 기출</category>
      <author>neveralone</author>
      <guid isPermaLink="true">https://iamneveralone.tistory.com/54</guid>
      <comments>https://iamneveralone.tistory.com/54#entry54comment</comments>
      <pubDate>Sun, 24 Sep 2023 14:58:55 +0900</pubDate>
    </item>
    <item>
      <title>[백준 14889] 스타트와 링크 (C++) - S1</title>
      <link>https://iamneveralone.tistory.com/53</link>
      <description>&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://www.acmicpc.net/problem/14889&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/14889&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695457956417&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;14889번: 스타트와 링크&quot; data-og-description=&quot;예제 2의 경우에 (1, 3, 6), (2, 4, 5)로 팀을 나누면 되고, 예제 3의 경우에는 (1, 2, 4, 5), (3, 6, 7, 8)로 팀을 나누면 된다.&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/14889&quot; data-og-url=&quot;https://www.acmicpc.net/problem/14889&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bGXb7S/hyTZb7MKaa/KUIMXMOY3zOuV4o4xQXEc1/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14889&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/14889&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bGXb7S/hyTZb7MKaa/KUIMXMOY3zOuV4o4xQXEc1/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;14889번: 스타트와 링크&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;예제 2의 경우에 (1, 3, 6), (2, 4, 5)로 팀을 나누면 되고, 예제 3의 경우에는 (1, 2, 4, 5), (3, 6, 7, 8)로 팀을 나누면 된다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;개요&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제를 읽자마자 &lt;b&gt;백트래킹&lt;/b&gt;을 이용해겠다고 생각했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;바로 이전에 백트래킹 문제를 한 번 풀어봤기 때문에 감을 살려서 도전했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러나, 백트래킹 함수를 구현할수록 코드가 너무 과하게 복잡해지는 느낌이 들었고, 테스트케이스 실행 시 자꾸 다른 답이 도출되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;결구 이 문제 또한 구글링을 시도했다...!&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구글링한 후 코드를 참고하고 이해한 후에, 다시 내 식대로 코드를 작성했는데 테스트케이스 3가지는 모두 통과하는데, 제출하면 자꾸만 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;시간 초과&lt;/b&gt;&lt;/span&gt;가 떴다....&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1시간 넘게 틀린 게 뭔지 찾았는데, &lt;b&gt;func(cnt + 1, i + 1)&lt;/b&gt;이라고 써야 하는데 func(cnt + 1, idx + 1)이라고 썼던 것이 문제였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제 풀이&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;백트래킹을 활용하는 문제이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;총 n명이 존재하는데, 스타트 팀에 n / 2명, 링크 팀에 n / 2명 이렇게 &lt;b&gt;중복 없이&lt;/b&gt; 팀이 이루어져야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;중복 체크를 위해 visited 배열을 사용하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;visited[i] = 1이면 스타트 팀에, visited[i] = 0이면 링크 팀에 배정하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 &lt;b&gt;이중 for문&lt;/b&gt;을 이용하여 팀에 포함된 스타트 팀, 링크 팀 각각의 팀원들의 능력치의 합을 구하였다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;func 함수를 재귀적으로 사용하는 for문에서 idx를 사용하지 않고 i = 0부터 계속 for문을 돌리면 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;시간 초과&lt;/b&gt;&lt;/span&gt;가 뜨게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;꼭 i = idx부터 시작하도록 해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;최종 결과값을 저장할 ans는 처음에 40000으로 초기화해주었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Sij는 100보다 작고, N &amp;lt;= 20이므로, 능력치의 전체 총합은 20 * 20 * 100 = 40000보다 작을 것이기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코드&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1695463238693&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstring&amp;gt;
#include &amp;lt;sstream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;deque&amp;gt;
#include &amp;lt;queue&amp;gt;
#include &amp;lt;map&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;bitset&amp;gt;
#include &amp;lt;cmath&amp;gt;

using namespace std;

int n, ans = 40000;
int arr[20][20];
int visited[20];

void func(int cnt, int idx) {
	if (cnt == (n / 2)) {
		vector&amp;lt;int&amp;gt; start, link;
		int start_score = 0, link_score = 0;
		for (int i = 0; i &amp;lt; n; i++) {
			if (visited[i]) start.push_back(i);
			else link.push_back(i);
		}
		for (int i = 0; i &amp;lt; (n / 2); i++) {
			for (int j = 0; j &amp;lt; (n / 2); j++) {
				start_score += arr[start[i]][start[j]];
				link_score += arr[link[i]][link[j]];
			}
		}
		int temp = abs(start_score - link_score);
		ans = min(ans, temp);

		return;
	}

	for (int i = idx; i &amp;lt; n; i++) {
		visited[i] = 1;
		func(cnt + 1, i + 1);
		visited[i] = 0;
	}
}

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

	cin &amp;gt;&amp;gt; n;

	for (int i = 0; i &amp;lt; n; i++) {
		for (int j = 0; j &amp;lt; n; j++) {
			cin &amp;gt;&amp;gt; arr[i][j];
		}
	}
	func(0, 0);
	cout &amp;lt;&amp;lt; ans;
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;padding: 0.3em 0.5em 0.3em 0.5em; margin: 0.5em 0em; color: #000000; border-left: 10px solid #000000; font-weight: bold; font-size: 20px;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;깨달은 점&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;백트래킹 함수를 구현하는 중간에 함수가 너무 복잡해지고 지저분해지면 뭔가 잘못된 것 같다는 의심을 할 필요가 있다는 생각이 들었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 func 함수의 인자에 사용되는 idx를 for문의 범위에 사용하는 자연스러운 흐름에 익숙해져야겠다는 생각 또한 들었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;연습만이 답인 것 같다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>백준 문제 리뷰/삼성 SW 기출</category>
      <author>neveralone</author>
      <guid isPermaLink="true">https://iamneveralone.tistory.com/53</guid>
      <comments>https://iamneveralone.tistory.com/53#entry53comment</comments>
      <pubDate>Sat, 23 Sep 2023 19:13:15 +0900</pubDate>
    </item>
  </channel>
</rss>