[C++] Relabel to front

  • Azurespace
    Azurespace
    #include<list>
    using namespace std;
    inline int min(const int a, const int b){
        return a>b?b:a;
    }
    /*  "Relabel to front" is one of the fastest algorithm to solve 
     *  Maximum Flow problem. This is a variation of Push-relabel algorithm.
     *
     *                        Jae ju, Kim
     *                        Azurespace
     */
    template<int N>
    class MaxFlow{
        static const int INF = 0x7fffffff;
        int capacity[N][N];
        int height[N];
        int residual[N];
        int index[N];
    public:
        void push(int u,int v){
            int send = min(capacity[u][v], residual[u]); 
            capacity[u][v] -= send;
            capacity[v][u] += send;
            residual[u] -= send;
            residual[v] += send;
        }
        void relabel(int u){
            int v, h = height[u];
            for(v = 0; v < N; ++v){
                if(capacity[u][v] > 0){
                    h = min(h, height[v]);                
                }
            }
            height[u] = h + 1;
        }
        void discharge(int u){
            int v;
            if(residual[u] > 0){
                while(index[u] < N){
                    v = index[u];
                    if(capacity[u][v] > 0 && height[u] > height[v])
                        push(u,v);
                    ++index[u];
                }
                relabel(u);
                index[u]=0;
            }
        }
        int flow(int s, int e){
            list<int> L;
            list<int>::iterator iter;
            int u, prev_height;
            for(u=0; u < N; ++u){
                residual[u] = 0;
                index[u] = 0;   
                height[u] = 0;
            }
            residual[s] = INF;       
            height[s] = N;
            for(u=0; u < N; ++u){
                push(s, u);
                L.push_back(u);
            }
            for(iter = L.begin(); iter != L.end(); ++iter){
                u = *iter;
                prev_height = height[u];
                discharge(u);
                if(height[u] != prev_height){
                    L.push_front(u);
                    L.erase(iter);
                    iter = L.begin();
                }
            }
            return residual[e];    
        }
    };
    int main(){ 
        return 0;
    }
    

    그냥 오랜만에 한번 짜 봤습니다
    조금 고치면 실제로 사용도 가능할 겁니다. 아마도(...)
    기억에 의존해서 짠 거라 틀릴지도?

    [이 글은 과거 홈페이지에서 이전된 글입니다. 원문보기]


    15년 전
2개의 댓글이 있습니다.
  • 샥후
    샥후

    틀렸네여


    15년 전 link
  • GondoR
    GondoR

    ㅇㅇ


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