codeforces863Fほとんど順列費用流

トピックポータル

質問の意味:

  列数、数字内の$ 1構築〜スコープN $、$ /和^要件{N} _ {I}カウント(I)^ {2} $最小、$カウント(I)$ Iの列の数を意味します出現数。そして、条件の2種類の列の数が満たされている、一つは$ a_i-> a_j $すべてのVより大きく、同様に$ a_i-> a_j $など、すべて未満のVです。

アイデア:

  まず第一に、我々は、上部及び特定の位置の下限値に制約を置くことができ、その後、位置は、建物の容量の両側に対応する全ての数字を入力し、その後の1をシンクするためのN個のデジタル建物容量のそれぞれができます側、一つは......、2 * J-1 $、$ 1,3,5の原価計算、その数は二回選択し、ちょうど取得した場合、建設側の後、プレフィックスは出現数の二乗です。

 

#pragma GCCの最適化(2)
 の#pragma G ++最適化(2)
 の#pragmaコメント(リンカー、 "/ STACK:102400000,102400000")
の#include <ビット/ STDC ++ H> 
の#include <cstdioを> 
する#include <ベクトル>
 の#define担当者(iは、、B)のための(iは= int型、iが<= bは、iが++)
 の#define DEP(I、B、A)(iはBを= int型;方には> =; i--)
 の#define CLR(B)のmemset(A、B、はsizeof(A))
 の#define PB一back
 の#define PII対<整数、整数>
 使用して 名前空間STDを、
typedefの長い 長いLL。
const  int型 MAXN = 200010 ;
CONST int型 INF = 0x3f3f3f3f 
LL RD()
{ 
    LL、X = 0、F = 1チャー CH = GETCHAR()。
    一方、(CH < ' 0 ' || CH> ' 9 '){ 場合(CH == ' - ')、F = - 1 ; CH = GETCHAR();}
     一方(CH> = ' 0 ' && CH <= ' 9 '){X = X * 10 + CH- ' 0 ' ; CH = GETCHAR();}
    リターンのx *のF; 
} 
の#include <ビット/ STDC ++ H>
 の#define CLR(B)のmemset(A、B、はsizeof(a))が
 使用 名前空間STDを、
typedefの長い 長いLL。
const  int型 MAXN = 1010 ;
const  int型 MAXM = 20010 ;
const  int型 INF = 0x3f3f3f3f 構造体のエッジ{
     INT 、次に、キャップ、流れ、コストに、

}エッジ[MAXM]。
構造体PP {
     int型、U、V、C、W。
} 【MAXN]。
int型ヘッド【MAXN]、TOL。
INT プレ[MAXN]、[MAXN] DIS。
BOOL VIS [MAXN]。
INT N = MAXN- 2 INTのN、Q、L [MAXN]、R [MAXN]。
ボイドのinit(){ 

    TOL = 0 
    memsetの(頭、 - 1はsizeof (ヘッド))。

} 
ボイド ADDV(INT U、INT V、int型のキャップ、int型のコスト){ 
    エッジ[TOL] .TO = V。
    エッジ[TOL]の.cap = キャップ。
    エッジ[TOL] .cost =コスト。
    エッジ[TOL] .flow
    CLR(DIS、INF)。= 0 ; 
    エッジ[TOL] .next = 頭部[U]。
    ヘッド[U] = TOL ++ 
    エッジ[TOL] .TO = U。
    エッジ[TOL]の.cap = 0 
    エッジ[TOL] .cost = - コスト。
    エッジ[TOL] .flow = 0 
    エッジ[TOL] .next = 頭部[V]。
    ヘッド[V] = TOL ++ 

} 
BOOL spfa(INT S、INT T){ 
    キュー < INT > Q。
    CLR(VIS、0)、CLR(プリ、 - 1)。

    DIS [S] = 0 ; 
    VIS [S] = 
    q.push(S); 
    しばらく(!q.empty()){
         int型のu = q.front(); 
        q.pop(); 
        VIS [U] = ;
        以下のためにint型 - ;!I = I =ヘッド[U] 1 ; I = {エッジ[I] .next)
             のint V = エッジ[I] .TO。

            もし(エッジ[I]の.cap>エッジ[I] .flow && DIS [V]> DIS [U] + エッジ[I] .cost){ 
                DIS [V] = DIS [U] + エッジ[I] .cost ;
                [V]事前 = ; I
                 IF(!{VIS [V])
                    VIS [V] = trueに; 
                    ; q.push(V)

                } 

            } 

        } 

    } 
    IF - (PRE [T] == 1リターン falseにし他の リターン 真へ; 

} 
// 最大流量を返し、最小のコストがコスト格納されている
INT minCostMaxflow(INT S、INT T、INTコスト){
     int型の流量=0 
    コスト = 0 一方、(spfa(S、T)){
         int型最小= INFと、
        int型 - ;!I = I =事前[T] 1 ; I =事前[エッジ[I ^ 1 {] .TO])
             であれば( -最小>エッジ[I]の.cap [i]は.flowエッジ)を
                最小 =エッジ[I]の.cap - エッジ[I] .flow。

        } 
        のためのint型 I =事前[T]; I =! - 1 ; I =事前[エッジ[I ^ 1 ] .TO]){ 
            エッジ[I] .flow + = 分; 
            エッジ[I ^ 1] .flow - = 分; 
            コスト [I] .cost * + =縁分; 

        } 
        フロー + = 分; 

    } 
    戻り流; 

} 
int型のmain(){ 
    CIN >> N >> Q。
    初期化(); 
    INT S = 0、T = 2 * N + 1 
    担当者(I、1 、N){ 
        ADDV(S、I、10 ); 
        R [I] = N。
        L [I] = 1 
        担当者(J、1 、N){
            ADDV(I+ N、T、12 * J- 1 )。
        } 
    } 
    int型フラグ= 1 一方、(q-- ){
         int型のOP、X、Y、V。
        scanf関数(" %D%D%D%D "、&​​OP、およびX&Y、およびV)。
        もし(OPの== 1 ){ 
            担当者(I、x、y)は{ 
                L [I] = MAX(L [i]は、V)。
            } 
        } { 
            担当者(I、x、y)は{ 
                R [I] = 分(R [i]は、V)。
            } 
        } 
    }
    担当者(I、1 、N){
         場合(L [I]> R [I]){ 
            フラグ = 0 破ります; 
        } 
        担当者(J、L [i]は、R [I]){ 
            ADDV(I、J + N、10 ); 
        } 
    } 
    もし(フラグ== 0 ){ 
        プット(" -1 " )。
        リターン 0 ; 
    } 
    int型C。
    minCostMaxflow(S、T、C)。
    coutの << C << てendl; 
    
}

 

おすすめ

転載: www.cnblogs.com/mountaink/p/11609772.html