BUS 질문드립니다

  • chongkong
    chongkong

    정확히는 Dinic 알고리즘 질문드립니다. 어쩌다 에드먼드 카프 알고리즘이 17700ms만에 통과가 되어 다른 분들의 답을 볼 기회가 생겨서 dinic 알고리즘을 알게 되었는데요, 다른 분들의 코드(종만님과 kcm님!)를 참고하여 디닉 알고리즘을 작성하였는데 에드먼드 카프가 통과한 저지에서 TLE가 나네요. 시간복잡도는 더 적으니 (그리고 다른 분들의 답안이 100ms 안에 AC된걸 볼 때) 무한루프를 도는 거라 생각되는데 bfs에서도, dfs에서도 영 문제가 될 만한 부분을 찾질 못하겠어서 이렇게 질문글을 올려봅니다.

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    using namespace std;
    
    const int INF = (unsigned)-1 >> 1;
    const int SOURCE = 0;
    const int SINK = 1;
    
    int T, N;
    
    struct Dinic {
        struct Edge {
            // deistination, reverse index, residual capacity
            int dest, rev, res;
            Edge(int _dest, int _rev, int _res) 
                : dest(_dest), rev(_rev), res(_res) {
    
            }
        };
    
        int _size;
        vector < vector < Edge > > _graph;
        vector < int > dist;
    
        Dinic(int size) {
            _size = size;
            _graph.resize(_size);
        }
    
        void addEdge(int here, int there, int capacity) {
            Edge forward = Edge(there, _graph[there].size(), capacity);
            Edge reverse = Edge(here, _graph[here].size(), 0);
            _graph[here].push_back(forward);
            _graph[there].push_back(reverse);
        }
    
        // assign levels to vertices by BFS
        // return 1 if sink is reachable
        int bfs(int source, int sink) {
            dist = vector < int > (_size, -1);
            queue < int > q;
    
            dist[source] = 0;
            q.push(source);
    
            while (!q.empty()) {
                int here = q.front(); q.pop();
                for (auto edge : _graph[here]) {
                    if (edge.res > 0 && dist[edge.dest] == -1) {
                        dist[edge.dest] = dist[here] + 1;
                        q.push(edge.dest);
                    }
                }
            }
    
            return dist[sink] != -1;
        }
    
        // find augmenting path by DFS
        int dfs(int here, int sink, int flow) {
            if (here == sink) {
                return flow;
            }
    
            for (auto &edge : _graph[here]) {
                if (dist[edge.dest] > dist[here] && edge.res > 0) {
                    int bottleneck = dfs(edge.dest, sink, min(flow, edge.res));
                    if (bottleneck > 0) {
                        edge.res -= bottleneck;
                        _graph[edge.dest][edge.rev].res += bottleneck;
                        return bottleneck;
                    }
                }
            }
            return 0;
        }
    
        int maxFlow(int source, int sink) {
            int ret = 0;
            // while sink is reachable
            while (bfs(source, sink)) {
                // increase by blocking flow
                while (int delta = dfs(source, sink, INF)) {
                    ret += delta;
                }
            }
            return ret;
        }
    };
    

    10년 전
0개의 댓글이 있습니다.
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.