문제 링크

첫 레드 문제 솔브입니다.
2100이 solved.ac 기준으로 대략 P3 정도 되는것 같아 2400정도면 P1~D5 정도 되지 않을까 싶어 하나만 풀어보자 싶어 도전해봤는데 역시 쉽지 않네요. 그래도 어떻게든 하나 잡았으니 만족합니다...
크기가 N×M이고 모든 요소가 0 또는 1인 배열 a가 있습니다.
저희는 배열의 요소를 하나 골라 0 또는 1로 변경하는 연산을 수행할 수 있고 해당 연산을 최소한으로 수행해서 i번째 행에는 1의 갯수가 Ai, j번째 열에는 1의 갯수가 Bj가 되도록 만들려고 합니다. (1≤i≤n,1≤j≤m)
먼저 입력에 따라 아래 그림과 같이 비용이 있는 유량 그래프로 모델링을 합니다.

그림이 너무 복잡해서 각 간선의 용량과 비용은 아래에 설명하겠습니다.
- source→ri,0 : 용량은 N−Ai, 비용은 ai,j로 설정합니다.
- source→ri,1 : 용량은 Ai, 비용은 1−ai,j로 설정합니다.
- ri,k→ai,j,k : 용량은 1, 비용은 0으로 설정합니다.
- ai,j,k→cj,k : 용량은 1, 비용은 0으로 설정합니다.
- cj,0→sink : 용량은 M−Bj, 비용은 0으로 설정합니다.
- cj,1→sink : 용량은 Bj, 비용은 0으로 설정합니다.
위 유량 그래프에서 source에서 sink로 유량을 흘려보내면 아래와 같은 사실을 얻을 수 있습니다.
- 최대 유량이 MN이면 연산을 통해 지문에서 요구하는 배열을 만들 수 있습니다. 반대로 최대 유량이 MN보다 작으면 연산을 아무리 해도 지문에서 요구하는 배열을 만들 수 없습니다.
- 지문에서 요구하는 배열을 만들 수 있다면 최대 유량을 흘려보내는데 드는 비용이 연산의 횟수가 됩니다. 당연히 최대 유량을 흘려보낼 때 드는 비용의 최솟값이 지문에서 요구하는 배열을 만들기 위한 연산의 최소 횟수가 됩니다.
즉, MCMF 알고리즘을 사용하면 답을 얻을 수 있습니다.
시간복잡도는 O(MNf)입니다. 사실 spfa 알고리즘의 경우 평균 O(E), 최악의 경우 O(VE)의 시간복잡도를 가지고 있어 최악의 경우 O(M2N2f)가 될 수도 있는게 아닌가 하고 생각해 봤습니다. 물론 그래프의 연결 구조까지 입력에 따라 수시로 바뀐다면 worst case를 저격하는게 가능할 수도 있습니다만 위 문제에서는 입력에 따라 간선의 비용(spfa에서 가중치 역할)이 바뀌지만 그래프의 간선의 연결 구조까지 바뀌지는 않습니다. 그래서 모델링한 그래프가 가중치가 어떻게 잘못 걸려서 worst case를 만들 수 있는 구조가 아니라면 괜찮을테고 이 문제에서는 그렇게 모델링이 가능해서 잘 도는것 같습니다. 물론 직접 돌려봐야 걸리는지 안 걸리는지 알 수 있을테니 만약에 돌렸는데 TLE가 난다면 다른 모델링을 생각해 봐야겠죠...