d[next]==-1 부분 때문에 오답이 됩니다.
SPFA의 기본 논리는 벨만 포드입니다. 벨만 포드 알고리즘에서는 어떤 노드에 방문했는지 여부를 따지지 않습니다.
아마 노드의 방문 여부를 체크하려고 하시는게 다익스트라 때문인 것으로 보이는데,
다익스트라의 경우 선택된 노드는 그 노드까지의 최소 비용이 보장 되기 때문에 노드 방문 여부를 통해 이전에 이 노드를 방문했었는지
체크하는 것입니다.-> 이전에 방문했던 적이 있므면 다시 방문한 이 동일한 노드 까지의 비용은 최소한 같거나 크기 때문.
그러나 벨만포드는 이미 방문했었던 노드라도 후에 더 작은 값이 들어 올 수 있기 때문에 위와 같이 이미 방문했는지 여부를 파악하여 그 노드 값의 갱신을 아예 제외 시켜버리니 오답이 됩니다. d[next]==-1부분만 지우고 제출하면 통과됩니다.
여담으로
for (int i = T; i != S; i = d[i]) Flow = min(Flow, c[d[i]][i] - f[d[i]][i]);
부분은 필요가 없습니다. 이 문제의 경우 만약 flow를 더 흘려보낼 수 있는 상황이라면 이는 무조건 flow가 1이기 때문입니다.
따라서
for (int i = T; i != S; i = d[i]) { min_cost += 1 * w[d[i]][i]; f[d[i]][i] += 1; f[i][d[i]] -= 1; } -> 이렇게 해줘도 맞는 답이 됩니다.
park780172 4년 전
우선 상당히 길고, 약간 복잡한 질문이라서 읽어주신 것만으로도 감사합니다.
구글링(?)을 해봐도 마땅히 제가 원하는 답을 얻지 못 하여 부득이하게 이 곳에 질문해봅니다.
MCMF 공부 중에 연습 문제로 이 문제를 풀어보았습니다.
제가 첨부한 코드는 일단 틀린 코드이고,
105번 째 줄을 101번 째 줄(주석)로 고치면 통과됩니다.
하지만, 제가 6086번 최대 유량을 풀 때는
http://boj.kr/1dafeccac76449c9a1e86861e80bd8b6에 있는 35번 째 줄처럼
'd[next] == -1'(아직 방문을 안 했다면)을 구현하였음에도 통과하였고,
11657번 타임머신을 SPFA로 풀 때는
http://boj.kr/f0280b69e90746dc916f760829a93632에 있는 47번 째 줄처럼
'dist[here] != INF'(출발점에서는 가지 못 하는 정점일 때는 무시)을 구현하였고 통과하였습니다.
그런데
이 문제(MCMF)에서는 위의 2가지 조건을 구현하면 틀리고,
왜 빼야 통과되는지 궁금합니다..
MCMF의 개념이 구글링해도 잘 나오지는 않더라구요 ㅠㅠ 뭔가 문제 위주로만 있어서..