※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 24977번 문제인 Visits이다.
문제는 아래 링크를 확인하자.

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

 

24977번: Visits

Each of Bessie’s $N$ ($2\le N\le 10^5$) bovine buddies (conveniently labeled $1\ldots N$) owns her own farm. For each $1\le i\le N$, buddy $i$ wants to visit buddy $a_i$ ($a_i\neq i$). Given a permutation $(p_1,p_2,\ldots, p_N)$ of $1\ldots N$, the visit

www.acmicpc.net

모든 소는 정확히 한 마리의 소를 향해 가고싶어하므로 주어진 그래프는 directed pseudoforest로 생각할 수 있다.

 

이 directed pseudoforest에서, 사이클을 이루지 않는 간선에 대응되는 소의 움직임은 사이클을 이루고 있는 에지에 대응되는 소의 움직임에 아무런 영향을 주지 않게 모든 움직임을 실행할 수 있게끔 항상 permutation을 구성할 수 있다는 점을 관찰하자.

 

또한, 각 cycle에서도 단 하나의 움직임을 제외한다면 모든 움직임을 실행할 수 있게끔 항상 permutation을 구성할 수 있다는 점을 관찰하자.

 

따라서, 주어진 그래프에서, moo의 횟수를 최대화하려면 각 사이클마다 가장 적은 moo를 하는 움직임을 제외한 모든 움직임을 실행하면 된다.

 

주어진 pseudoforest에서 사이클을 탐색해나가며 문제를 해결하자.

 

아래는 제출한 소스코드이다.

#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;

pair<int, ll> G[100001];
int visited[100001]; // 0:방문함 1:방문함(사이클일 시 재방문안함) 2:방문함(사이클일 시 재방문함 / 사이클 가능성 없음)

ll dfs_cyc(int cur) {
	visited[cur] = 2;
	if (visited[G[cur].first] == 2) return G[cur].second;
	else return min(G[cur].second, dfs_cyc(G[cur].first));
}

ll dfs(int cur) {
	visited[cur] = 1;
	if (visited[G[cur].first] == 0) {
		ll ret = dfs(G[cur].first);
		visited[cur] = 2;
		return ret;
	}
	if (visited[G[cur].first] == 1) return dfs_cyc(G[cur].first);
	
	visited[cur] = 2;
	return 0; // visited[G[cur].first == 2
}

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

	ll ans = 0;

	int N; cin >> N;
	for (int i = 1; i <= N; i++) {
		int x; ll moo; cin >> x >> moo;
		ans += moo;
		G[i] = make_pair(x, moo);
	}

	for (int i = 1; i <= N; i++) {
		if (visited[i]) continue;
		ans -= dfs(i);
	}

	cout << ans;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 24924 // C++] Card Divisibility  (0) 2022.05.01
[BOJ 24923 // C++] Canadians, eh?  (0) 2022.05.01
[BOJ 24978 // C++] Subset Equality  (0) 2022.04.29
[BOJ 24979 // C++] COW Operations  (0) 2022.04.28
[BOJ 24980 // C++] Photoshoot  (0) 2022.04.27

+ Recent posts