BOJ 23887 프린트 전달
·298 words·2 mins
📝 문제 정보 # 링크: https://www.acmicpc.net/problem/23887 🧐 관찰 및 접근 # 설명을 대충 읽는데, BFS맛이 난다 허걱, 최대 학생이 25000명이라 나이브하게는 조금 곤란하긴 하다 근데 뭔가 트리처럼 해석할 수도 있을 것 같은데? MST인가? 아 근데 좀 유향 그래프? 맛인데… 위상정렬이네 이거 엥? 근데 이게 $2$번 학생이 $5, 6$번한테 받을 수 있다고해서 무조건 $5$번한테만 받는건 아니네? 그러면 다시 트리맛으로? 그러면 뭔가 트리의 지름을 최소화하는 느낌으로 가야하는 것 같은데… 그래프에서 가장 먼 두 점을 어떻게 구할 수 있을까? ???????? 아니 문제에서 $S$가 주어지는거였네 그러면 그냥 BFS를 돌리자 구현이 상당히 재밌다! 💻 풀이 # 코드 (C++): void solve(){ int N, M, K; cin >> N >> M >> K; vector<vector<int>> board(N, vector<int>(M, 0)); vector<pii> students(K+1); vector<bool> visited(K+1); rep(i, 1, K+1){ int x, y; cin >> x >> y; x--; y--; students[i] = {x, y}; board[x][y] = i; } int S; cin >> S; set<int> Q; Q.insert(S); visited[S] = true; vector<vector<int>> links(K+1); vector<int> dx = {-1, -1, -1, 0, 0, 1, 1, 1}; vector<int> dy = {-1, 0, 1, -1, 1, -1, 0, 1}; while(!Q.empty()){ set<int> nQ; for(auto cur: Q){ auto [cx, cy] = students[cur]; rep(d, 0, 8){ int nx = cx + dx[d]; int ny = cy + dy[d]; if(nx < 0 || nx >= N || ny < 0 || ny >= M) continue; if(board[nx][ny] == 0) continue; int nxt = board[nx][ny]; if(visited[nxt]) continue; visited[nxt] = true; links[cur].push_back(nxt); nQ.insert(nxt); } } swap(Q, nQ); } rep(i, 1, K+1) if(!visited[i]){ cout << -1; return; } vector<int> sz(K+1); function<void(int)> dfs = [&](int cur){ sz[cur] = 1; for(auto nxt: links[cur]){ dfs(nxt); sz[cur] += sz[nxt]; } }; dfs(S); rep(i, 1, K+1) cout << sz[i] << ' '; } 🔒 구현 코드 잠금