순간을 성실히, 화려함보단 꾸준함을

[ boj : 21738 ] 얼음깨기 펭귄 본문

알고리즘,SQL/백준,BOJ

[ boj : 21738 ] 얼음깨기 펭귄

폭발토끼 2021. 7. 17. 09:29

https://www.acmicpc.net/problem/21738

 

21738번: 얼음깨기 펭귄

첫째 줄에 얼음 블록의 개수 $N$($ 3 \leq N \leq 328\,000$)과 지지대의 역할을 하게 되는 얼음의 개수 $S$($ 2 \leq S \leq N-1$), 펭귄이 위치한 얼음 블록의 번호 $P$($ S \lt P \leq N$)가 주어진다. 지지대의 역

www.acmicpc.net

문제 : 팽귄이 물에 안빠지도록 하기까지 깨트릴수 있는 최대 얼음의 개수를 구하시오

해설 : "이때, 지지대가 연결되어 있다는 것은 지지대로부터 서로 다른 일반 얼음들을 통해 연결 관계가 이어져 있는 것을 이야기한다" 라는 문구를 잘 생각해보면, 지지대는 다른 지지대와 펭귄이 있는 위치를 제외하고는 연결이 되지 않는다는 것을 알 수 있습니다.

따라서 그냥 각 지지대까지의 depth를 구한다음에 정렬하여 2개를 선택해서 총 얼음의 개수에서 빼주면 됩니다.

#include<bits/stdc++.h>

using namespace std;

const int SIZE = 328010;
int pos[SIZE],visit[SIZE];
vector<int> adj[SIZE];
vector<int> dist;

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, p, s;
	cin >> n >> s >> p;
	int x, y;
	for (int i = 0; i < n-1; i++) {
		cin >> x >> y;
		adj[x].push_back(y);
		adj[y].push_back(x);
		if(i<s) pos[i + 1] = 1;
	}
	int sum = 0, cnt = 0, check = 0;
	queue<int> q;
	q.push(p);
	visit[p] = 1;
	while (!q.empty())
	{
		cnt++;
		int size = q.size();
		for (int time = 0; time < size; time++) {
			int cur = q.front();
			q.pop();

			for (int i = 0; i < adj[cur].size(); i++) {
				if (!visit[adj[cur][i]]) {
					if (pos[adj[cur][i]] == 1) 
						dist.push_back(cnt);					
					visit[adj[cur][i]] = 1;
					q.push(adj[cur][i]);
				}
			}
		}
	}		
	sort(dist.begin(), dist.end());
	cout << n - dist[0] - dist[1] - 1;
	return 0;
}