dinic最大流量(アークの最適化)

Dinic- 有当前弧优化
 // STATUS:G ++ _ AC_3891MS_8528KB 
する#include <stdio.hに> 
する#include <stdlib.h>に含ま
する#include < 文字列の.h> 
の#include <math.h>の
書式#include <iostreamの> 
する#include < 文字列 > 
の#include <アルゴリズム> 
書式#include <ベクトル> 
の#include <キュー> 
の#include <スタック> 
の#include <マップ>
 使用して 名前空間はstdを、
#defineは LL長い長
 の#define MAX(A、B)((A)>(B)?(A):( B))
 #defineする MIN(A、B)を((A)<(B)?(A) :
MEM(A、B)のmemset(A、B、はsizeof(A))
 の#define LSON Lを、中間、RT << 1つ
 の#define中間+ 1 rson、R、RT << 1 | 1
 のconst  INT MAX = 20010、INF = 0x3f3f3f3f 

構造体のエッジ{
     int型、U、V、キャップ。
} E [MAX * 30 ]。

INT最初の[MAX]、次の[MAX * 30 ]、D [MAX]、[MAX]をcur変換。
INTのN、M、S、T、MM。

 adde1(int型int型、B、int型のvalを)
{
    E [mm]と.U = A; E [mm]で.V = B。
    E [mm]との.cap = ヴァル。
    次さ[mm] =最初の[A]、最初の[A] = MM ++ 
    E [mm]と.U = B; E [mm]で.V = A。
    E [mm]との.cap = 0 
    次さ[mm] =最初の[B];最初の[B] = MM ++ 
}

 adde2(int型int型、B、int型のvalを)
{
    E [mm]と.U = A; E [mm]で.V = B。
    E [mm]との.cap = ヴァル。
    次さ[mm] =最初の[A]、最初の[A] = MM ++ 
    E [mm]と.U = B; E [mm]で.V = A。
    E [mm]との.cap = ヴァル。
    次さ[mm] =最初の[B];最初の[B] = MM ++ 
}

int型BFS()
{
    int型のx、I、J。
    キュー < 整数 > Q;
    MEM(D、0 );
    q.push(S);
    D [S] = 1 しばらく(!q.empty()){
        X = q.front(); q.pop()。
         - ;(!I = I =最初の[X] 1 ; I = {次の[I])
             であれば(E [I]の.cap &&!D [E [I] .V]){
                D [E [I] .V] = D [X] + 1 
                q.push(E [I] .V)。
            }
        }
    }
    戻りD [T]。
}

int型 DFS(int型のx、int型A)
{
    もし(X == T || == 0を返しますint型の F、流量= 0 INT&I = CUR [X]; I =! - 1 ; iが= 次の[I]){
         場合(D [X] + 1 == D [E [I] .V] &&(= F (DFS E [I] .V、MIN(、E [I]の.cap)))){
            そして[I]の.cap - = F。
            そして[I ^ 1 ]の.cap + = F。
            フロー + = F。
            A - = F。
            もし(A!)破ります
        }
    }
    リターンフロー;
}

int型dinic()
{
    int型 I、フロー= 0を一方、(BFS()){
         (i = 0 ; I <= T; iは++)CUR [I] = 最初の[I]。
        フロー + = DFS(S、INF)。
    }
    リターンフロー;
}

int型のmain()
{
 //    freopenは( "in.txt"、 "R"、STDIN)。
    int型I、A、B、ヴァル。
    一方、(〜のscanf(" %d個の%のD "、&​​N、&M))
    {
        MM = 0 
        MEM(第一、 - 1 )。
        S = 0、T = N + 1 (i = 1 ; iが<= N; iは++ ){
            scanf関数(" %D%dの"、&​​、&B)。
            adde1(S、I、A)。
            adde1(I、T、B)。
        }
        (i = 0 ; iがmを<Iは++ ){
            scanf関数(" %D%D%D "、&​​、&B、&ヴァル)。
            adde2(A、B、ヴァル)。
        }

        printf(" %d個の\ n " 、dinic())。
    }
    リターン 0 ;
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/xiaolaji/p/11766588.html