4991. ๋ก๋ด์ฒญ์๊ธฐ
by rlaehddnd0422https://www.acmicpc.net/problem/4991
4991๋ฒ: ๋ก๋ด ์ฒญ์๊ธฐ
๊ฐ๊ฐ์ ํ ์คํธ ์ผ์ด์ค๋ง๋ค ๋๋ฌ์ด ์นธ์ ๋ชจ๋ ๊นจ๋ํ ์นธ์ผ๋ก ๋ฐ๊พธ๋ ์ด๋ ํ์์ ์ต์๊ฐ์ ํ ์ค์ ํ๋์ฉ ์ถ๋ ฅํ๋ค. ๋ง์ฝ, ๋ฐฉ๋ฌธํ ์ ์๋ ๋๋ฌ์ด ์นธ์ด ์กด์ฌํ๋ ๊ฒฝ์ฐ์๋ -1์ ์ถ๋ ฅํ๋ค.
www.acmicpc.net


Point
1. ๋ก๋ด์ฒญ์๊ธฐ(o)์์ ๋ชจ๋ ๋๋ฌ์ด ์นธ(*)์ผ๋ก ์ด๋ํ๋๋ฐ ํ์ํ ์ต์ ๋น์ฉ
2. ๋๋ฌ์ด ์นธ(*)์ ์ต๋ ๊ฐ์๋ 10๊ฐ
3. ๋๋ฌ์ด ์นธ์ ๋ฐฉ๋ฌธํ๋ ์์์ ๋ฐ๋ผ ๋น์ฉ์ด ๋ฌ๋ผ์ง๋ค.

๋ฐฉ๋ฌธํ๋ ์์์ ๋ฐ๋ผ ๋น์ฉ์ด ๋ฌ๋ผ์ง๋ค.
์ฐ๋ ๊ธฐ๊ฐ 3๊ฐ์ธ ๊ฒฝ์ฐ์๋ 3! = 6๊ฐ์ง์ ๊ฒฝ์ฐ์ ์๊ฐ ์กด์ฌํ๋ค.
์ฐ๋ ๊ธฐ์ ์ต๋ ๊ฐ์๋ 10๊ฐ์ด๋ฏ๋ก ์ต๋ 10! =~ 3,600,000 ๊ฒฝ์ฐ์ ์๊ฐ ์กด์ฌํ๋ค.
๊ทธ๋ ๋ค๋ฉด ๋๋ฌ์ด ์นธ(*)์ ์ง์ ์ ๋ฒกํฐ์ ๋ฃ๊ณ next_permutation์์์ bfs๋ฅผ ๋๋ฆฌ๋ฉด ์ด๋จ๊น?
#include <iostream> #include <vector> #include <algorithm> #include <utility> #include <queue> #define FASTio ios_base :: sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL) #define endl '\n' using namespace std; int n,m; int dy[]={-1,1,0,0}; int dx[]={0,0,-1,1}; int bfs(int n,int m,int y,int x,vector<vector<char>> &area,vector<pair<int,int>>&v) { int sum = 0; int starty = y; int startx = x; for(int i=0;i<v.size();i++) { vector<vector<int>> visited(n+1,vector<int>(m+1,0)); vector<vector<bool>> check(n,vector<bool>(m+1,false)); queue <pair<int,int>> q; q.push(make_pair(starty,startx)); while(!q.empty()) { int y = q.front().first; int x = q.front().second; check[y][x] = true; q.pop(); if(y==v[i].first && x==v[i].second) { starty = y; startx = x; sum += visited[y-1][x-1]; } else { for(int k=0;k<4;k++) { int ny = y + dy[k]; int nx = x + dx[k]; if(ny>=0 && nx>=0 && ny<n && nx<m) { if(area[ny][nx]!='x' && check[ny][nx]==false) { check[ny][nx]=true; q.push(make_pair(ny,nx)); visited[ny][nx] = visited[y][x]+1; } } } } } } return sum; } int k; int main() { FASTio; while(1) { cin >> m >> n; if(n==0 && m==0) break; else { vector<vector<char>> area(n+1,vector<char>(m+1)); vector<pair<int,int>> v; int ans = 999999; int y,x; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { cin >> area[i][j]; if(area[i][j]=='o') { y = i; x = j; } else if(area[i][j]=='*') { v.push_back(make_pair(i,j)); } } } do { ans = min(ans,bfs(n,m,y,x,area,v)); } while (next_permutation(v.begin(),v.end())); if(ans==0) cout << -1 << endl; else cout << ans << endl; } } return 0; }
์ด๋ ๊ฒํ๋ฉด next_permutation ์์์ bfs๋ฅผ ์ํํ๊ธฐ ๋๋ฌธ์ O(10! * NM(BFS ์ํ์๊ฐ))์ ์๊ฐ์ด ๋ฐ์ํ์ฌ ์๊ฐ์ด๊ณผ๊ฐ ๋ฐ์ํ๋ค.

๋ฐ๋ผ์ ๋ค์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ ๋ฐฉ์์ ์ด์ฉํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.

Step 1 . dust_dist[0][1~๋๋ฌ์ด ์นธ ์] => ๋ก๋ด์ฒญ์๊ธฐ์์ ๊ฐ ๋๋ฌ์ด์นธ์ผ๋ก ๊ฐ๋ ๊ฑฐ๋ฆฌ๋ฅผ BFS๋ก ๋ฏธ๋ฆฌ ๊ตฌํ๋ค.
Step 2. dust_dist[i][j]์ i์ง์ ์์ j์ง์ ์ผ๋ก ๊ฐ๋ ๊ฑฐ๋ฆฌ๋ฅผ BFS๋ฅผ ํตํด ๋ฏธ๋ฆฌ ๊ตฌํด ๋๋๋ค.
Step 3. next_permutation์ ํตํด dust_dist์ ์ ์ฅ๋ ๊ฐ์ ์ด์ฉํ์ฌ ์ ํด์ง ์์๋๋ก ์ด ๊ฑฐ๋ฆฌ ๊ณ์ฐํ์ฌ ์ต์๊ฑฐ๋ฆฌ๋ฅผ ์ ์ฅํ๋ค.
์ด๋ ๊ฒ ํ๋ฉด ์์ ์ฝ๋๊ฐ O(10! * NM)์ด ๊ฑธ๋ ธ๋ค๋ฉด ์ด ๋ฐฉ๋ฒ์์๋ next_permutation์ ๋๋ฆด ๋๋ง๋ค ๋ด๋ถ์์ BFS๋ฅผ ์ํํ๋ ๊ฒ์ด ์๋๋ผ ๋ฏธ๋ฆฌ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ์ฐํด ๋๋ค๋ ์ ์์ O(10! + NM)์ผ๋ก ์์ฒญ๋ ์๊ฐ๊ฐ์๋ฅผ ๋ณผ ์ ์๋ค.
์์ค์ฝ๋
#include <iostream> #include <vector> #include <algorithm> #include <utility> #include <queue> #define FASTio ios_base :: sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL) #define endl '\n' using namespace std; int n,m; int dy[]={-1,1,0,0}; int dx[]={0,0,-1,1}; int bfs(int n, int m, int y,int x,int desty,int destx,vector<vector<char>>&area) { vector<vector<int>> visited(n+1,vector<int>(m+1,0)); vector<vector<bool>> check(n+1,vector<bool>(m+1,false)); check[y][x] = true; queue <pair<int,int>> q; q.push(make_pair(y,x)); while(!q.empty()) { int y = q.front().first; int x = q.front().second; q.pop(); if(y==desty && x==destx) { break; } else { for(int k=0;k<4;k++) { int ny = y + dy[k]; int nx = x + dx[k]; if(ny>=0 && nx>=0 && ny<n && nx<m) { if(area[ny][nx]!='x' && check[ny][nx]==false) { check[ny][nx]=true; q.push(make_pair(ny,nx)); visited[ny][nx] = visited[y][x]+1; } } } } } return visited[desty][destx]; } int main() { FASTio; while(1) { cin >> m >> n; if(n==0 && m==0) break; else { vector<vector<char>> area(n+1,vector<char>(m+1)); vector<pair<int,int>> v(1); int ans = -1; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { cin >> area[i][j]; if(area[i][j]=='o') { v[0] = make_pair(i,j); } else if(area[i][j]=='*') { v.push_back(make_pair(i,j)); } } } vector<vector<int>> dust_dist(v.size(),vector<int>(v.size(),0)); // ๋ก๋ด์ฒญ์๊ธฐ -> *๊น์ง์ ๊ฑฐ๋ฆฌ ๋ชจ๋ ๊ณ์ฐํด์ ์ ์ฅ for(int i=1;i<v.size();i++) { int dist = bfs(n,m,v[0].first,v[0].second,v[i].first,v[i].second,area); dust_dist[0][i] = dist; } // *๋ค ๊ฐ์ ๊ฑฐ๋ฆฌ for(int i=1;i<v.size();i++) { for(int j=1;j<v.size();j++) { dust_dist[i][j] = bfs(n,m,v[i].first,v[i].second,v[j].first,v[j].second,area); } } vector<int> order(v.size()-1); for(int i=0;i<order.size();i++) { order[i] = i+1; } sort(order.begin(),order.end()); do { bool itcant = false; int sum = dust_dist[0][order[0]]; // ์ฒซ๋ฒ์งธ *๋ก ๋ชป๊ฐ๋ฉด ๋ค์ ์กฐํฉ ์ดํด๋ณด๊ธฐ if(sum==0) { continue; } for(int i=0;i<order.size()-1;i++) { // * -> * ๋ชป๊ฐ๋ฉด ์ข
๋ฃ if(dust_dist[order[i]][order[i+1]]==0) { itcant = true; break; } // sum์ ๋จผ์ง๊ฑฐ๋ฆฌ ๋ํด์ฃผ๊ธฐ sum += dust_dist[order[i]][order[i+1]]; } if(itcant==true) { continue; } else { if(ans==-1 || ans>sum) { ans = sum; } } } while (next_permutation(order.begin(),order.end())); cout << ans << endl; } } return 0; }

๋ฌธ์ ๋ฅผ ์ฒ์ ๋ณด๊ณ ๋์๋ ์ฌ์๋ณด์๋๋ฐ, ํ๋ฉด์ ์ฝ์ง ์๋ค๋ ๊ฑธ ๋๊ผ๋ค.
์ฒ์์ ๊ตฌํํ๋ ๋ถ๋ถ์์ ์๊ฐํ ๋๋ก ๋์๊ฐ์ง ์์ ์ด๋ ค์ ๊ณ ๊ตฌํ ๋์๋ ์๊ฐ์ด๊ณผ๊ฐ ๋ฐ์ํด์ ์ด๋ป๊ฒ ์๊ฐ์ ์ค์ฌ์ผ ํ ์ง ๊ฐ์ด ์ค์ง ์์๋ค. ๊ตฌํํ๋ ์ฐ์ต์ ๋ง์ด ํด๋ณด๊ณ , ์๊ฐ์ด๊ณผ๋ฅผ ์ค์ด๋ ๋ฐฉ๋ฒ์ ๋ํด์ ๋ง์ด ๊ณ ๋ฏผํด๋ด์ผ๊ฒ ๋ค...
๋ธ๋ก๊ทธ์ ์ ๋ณด
Study Repository
rlaehddnd0422