[羅区P3227] [HNOI2013】カットケーキ

タイトル効果: $ nの\回数Mの$カットケーキは、各位置の高さは、最大4つの高さユニコムに$ $ [1、k]は、それぞれが2つのセル間に必要な高いコストを有するとの間であってもよいです$のD $の違いは、実現可能な最小コストを尋ねました。$ N、M、K、D

解決策:ネットワークフロー、位相差条件を考慮せずには、$ D $です、そして$私は$ドットを接続しても、$ 1 $ポイント容量の$ \のinftyの$の高さで、ソース、高さそれぞれの場所のためのポイントを構築することができます容量を犠牲にしてミーティングポイントに接続された容量、$ kは$高さを犠牲に$ I + 1 $点のこの高さ位置、まで。最小カットを実行します。

$ \ $ inftyのエッジの二つの隣接点$ A、Bの$、B_に接続$ a_iを\ {ID} $容量のために、$ Dが$条件の違いを検討され、したがって、2つの定義された点を強制最小距離は、最小カット実行中に、切断された$ Dが$以下でなければなりません

カードのスポット:より多くの$ K $倍を支払うために時間をフチ、別の$ TLE $と$ REの$が得られ

 

C ++コード:

#include <cstdioを> 
する#include <CCTYPE> 
の#include <アルゴリズム> 
のconst int型INF = 0x3f3f3f3f。

名前空間std { 
	構造体のIStream { 
に#define M(1 << 24 | 3)
		チャーBUF [M]、* CH = BUF - 1。
		インラインのIStream(){関数fread(BUF、1、M、STDIN)。} 
		インラインのIStream&演算子>>(INT&X){ 
			一方(isspace(* ++ CH))。
			X = X * 10 +(* CH&15)(; isdigit(* ++ CH)X = * CH&15)のために、
			*これを返します。
		} 
Mの#undef 
	} CIN。
	構造体のostream { 
に#define M(1 << 10 | 3)
		チャーBUF [M]、* CH = BUF - 1。
		インラインのostream&演算子<<(INT X){  
			(!x)の場合{* ++ CH = '0'; *これを返します;}
			静的INT S [20]、*トップ。トップ= S;
			(X){* ++トップ= X%ながら10 ^ 48。X / = 10;} 
			ため(;!トップ= S; --top)* ++ CH = *トップ。
			*これを返します。
		} 
		インラインのostream&演算子<<(CONSTチャーX){* ++ CH = X。戻り*この;} 
		インライン〜のostream(){関数fwrite(BUF、1、CH - BUF + 1、STDOUT)。} 
Mの#undef 
	} COUT。
} 

名前空間Network_Flow { 
	CONST INT MAXN = 50 * 50 * 50、MAXM = MAXN * 6。

	INT LST [MAXN]、ヘッド[MAXN]、CNT = 1。
	構造体のエッジ{ 
		にINT、NXT、W。
	} E [MAXM << 1]。
	ボイドaddedge {(int型B、INT C INT)
		E [++ CNT] =(エッジ){B、ヘッド[A]、C}。[A] = CNTヘッド。
		E [++ CNT] =(エッジ){、ヘッド[B]、0}。ヘッド[B] = CNT。
	} 

	ST編、N、MFをint型、
	INT GAP [MAXN]、DIS [MAXN]、Q [MAXN]、H、T。
	INIT()を無効{ 
		GAP [DIS [Q [H = T = 0] = ED = 1] = 1。
		[i]は[I] =ヘッドLST;(++ iの;私は=編<I = STをint型)について 
		一方で(H <= T){ 
			int型、U = Q [H ++]。
			{(; I I = E [i]は.nxt I =ヘッド[U]、V INT)のために
				、V = E [I] .TO。
				もし{(DIS [V]!)
					++ GAPは[DIS [V] DISを= [U] + 1]。
					Q [++のT] = V。
				} 
			} 
		} 
	} 
	int型DFS(INT U、INT低い){ 
		低IF返す(ロー|| Uは== ED!)。
		、RESが= 0をW INT。
		用(INT&I = LST [U]、V; I; I = E [I] .nxt)IF(E [I] .W){ 
			V = E [I] .TO。
			IF(DIS [U] == DIS [V] + 1){ 
				W = DFS(V、STD ::分(低、E [I] .W))。
				RES低+ = W、 - = W。
				E [i]は.W - = W、E [I ^ 1] .W + = W。
				もしリターン解像度(低いです!)。
			} 
		} 
		もし- DIS [ST] = N + 1(GAP [DIS [U]]!)。
		++ GAP [++ DIS [U]、LST [U] =頭部[U]。
		解像度を返します。
	} 
	ボイドISAP(INT S、T INT){ 
		ST = S、ED = T、N = T - S + 1。
		その中に(); 一方、(DIS [ST] <= N)MF + = DFS(ST、INF)。
	} 
} 

int型N、M、H、D。
int型V [50] [50] [50]。
int型のPOS [50] [50] [50]、IDX、ST、エド。

ボイドaddedge(int型のx、int型のY、int型Z、INT W){ 
	(INT I = D + 1; iは= Hを<; ++ i)について
		Network_Flow :: addedge(POS [X] [Y] [i]は、 POS [Z] [W] [I - D]、INF)。
} 
int型のmain(){ 
		用(int型J = 1; J <= N; ++ j)は 
	のstd :: CIN >> N >> M >> H >> D。
	以下のために(INT i = 1; iが= hを<; ++ I)
			のために(int型のk = 1; K <= M; ++ K){ 
				POS [J] [K] [I] = ++ IDX。
				std :: cinを>> V [J] [K] [i]は、
			} 
	ST = 0、ED = ++ IDX。
	以下のための(iは1 = int型、iが<= N; I ++)
		のために(INT J = 1; J <= M; ++ J){ 
			ため(int型K = 1; <= hをk個; ++ K){ 
				もし(K == 1)Network_Flow :: addedge(ST、POS [I] [J] [K]、INF)。
				もし(K == H)Network_Flow :: addedge(POS [I] [J] [K]、編、V [i]は[J] [K])。
				他Network_Flow :: addedge(POS [I] [J] [K]、POS [I] [J] [K + 1]、V [i]は[J] [K])。
			} 
			IF(I = 1!)addedge(I、J、I - 1、J); 
			(!I = N)の場合addedge(I、J、I + 1、j)は、
			(もし!J = 1)addedge(I、J、I、J - 1); 
			(もし!J = N)addedge(I、J、I、J + 1); 
		}
	Network_Flow :: ISAP(ST編); 
	std :: coutの<< Network_Flow :: MF << '\ nの'; 
	0を返します。
}

  

おすすめ

転載: www.cnblogs.com/Memory-of-winter/p/11272923.html