문제 링크
- https://icpc.me/19022
사용 알고리즘
- MCMF
풀이
수렴하지 않는 경우가 있다면 문제를 안 냈을 것 같으니 항상 수렴한다고 믿고 문제를 풀어봅시다.
$k$가 무한대로 발산하면 대부분의 유량이 사이클 안에 머물러 있고 일부만 싱크로 흘러가게 됩니다. 그러므로 일단 소스에서 유량을 최대한 많이 방출한 다음, 사이클 안에서 계속 도는 것을 최소화하는 방향으로 접근할 수 있습니다.
만약 어떤 정점 $u$에서 나간 유량이 $u$로 돌아오면 사이클이 만들어지고, 만약 사이클 밖으로 나갈 수 있었다면 $u$로 돌아오기 전에 밖으로 나갔을 것이기 때문에 $u \rightarrow \cdots \rightarrow u$ 꼴의 유량은 항상 사이클에 머물러 있는 유량입니다. 즉, $u \rightarrow \cdots \rightarrow u$ 꼴의 경로 개수를 최소화하는 문제가 됩니다.
예제는 이런 형태의 그래프입니다.
각각의 사이클마다 그 사이클에서 흐를 수 있는 유량은 (정점에서 나가는 간선의 용량) + (정점으로 들어가는 간선의 용량)보다 작거나 같습니다. 따라서 소스에서 각 정점으로 $in + out$ 만큼의 유량을 보낸 다음, 싱크로 내보낼 수 있는 유량을 전부 빼내고 남은 유량들을 사이클에서 돌린다고 생각해도 됩니다.
유량이 사이클에 머물러 있다는 것은 $L(u)$와 $R(u)$를 동시에 지난다는 뜻이므로, 위 사진에서 빨간 간선에 흐르는 유량을 최소화하면 된다는 것을 알 수 있습니다.
따라서 이런 식으로 그래프를 만든 다음, 빨간색 간선의 비용을 1로 설정해서 MCMF를 돌리면 문제를 해결할 수 있습니다.
전체 코드
1 |
|