フェイス質問
https://www.luogu.org/problem/P3756
問題の解決策
図$ + $ファンシー四半期染色
書式#include <cstdioを> する#include <CStringの> の#include <iostreamの> の#include <キュー> の#include <ベクトル> の#include <マップ> 書式#include <ユーティリティ> に#define里レジスタint型 の#define N 200050 の#define INF十億七 の#define S 0 の#define T(CC + 1) 使用して 名前空間STDを、 CONSTの INT DX [] = { 0、1、0、 - 1 }、DY [] = { 1、0、 - 1、0 }。 int型、N、R、C、X [N]、Y [N]、Z [N]。 INT における[N]、OU [N]、CC。 マップ <ペア< int型、int型 >、int型 > S; 構造体グラフ{ ベクトル < INT > ED [N]。 ベクトル < 整数 > に、ワット。 INT D [N]、CUR [N]。 ボイド add_edge(int型 U、int型 V、int型TW){ to.push_back(V)。w.push_back(TW)。ED [U] .push_back(to.size() - 1 )。 to.push_back(U)。w.push_back(0); ED [V] .push_back(to.size() - 1 )。 } BOOL BFS(){ キュー < INT > Q。 memsetの(D、0x3fを、はsizeof (d)参照)。 D [S] = 0 ; q.push(S)。 一方、(!q.empty()){ int型のx = q.front()。q.pop(); 用(RI i = 0 ; iが編<[X] .size(); iは++ ){ int型、E = ED [X] [I]; もし(D [X] + 1 <D [乃至[E] && W [E]){ D [E] [へ] [X] + = D 1; ([E]に)q.push。 } } } 戻り D [T] < INF。 } INT DFS(int型のx、int型の制限){ 場合(X == T ||限界== 0)リターンリミット。 int型の合計= 0 ; 用(RI&I = CUR [X]; iは<ED [X] .size(); iは++ ){ int型、E = ED [X] [I]; もし([E] W && D [X] + 1 ==のD [] E [に対して]){ int型、F = DFS([E]に分(限界、W [E]))。 もし(!F)続け; 和 + = F。リミット-側= F。 W [E] - = F。[W 1 ^ E] + = F。 もし(!リミット)リターン合計。 } } 戻り値の和。 } int型dinic(){ int型 RET = 0 。 一方、(BFS()){ memsetの(CUR、0、はsizeof (CUR))。 RET + = DFS(S、INF)。 } 戻りRET。 } } G。 int型コル(int型のx、int型Y){ 場合(Yの%2 == 0 ){ 場合(X%4 == 0)リターン 4 。 そう であれば(X%4 == 1)リターン 3 。 そう であれば(X%4 == 2)リターン 2 。 そう であれば(X%4 == 3)リターン 1 。 } 他{ 場合(Xの%4 == 0)リターン 3 。 そう であれば(X%4 == 1)リターン 4 。 そう であれば(X%4 == 2)リターン 1 。 そう であれば(X%4 == 3)リターン 2 。 } } int型のmain(){ scanf関数(" %D%D%D "、&C&R、&N)。 用(RI i = 1 ; iが<= N; iが++ ){ scanf関数("%D%D%D 」、およびX [i]は、&Y [i]は、&Z [i])と; 場合(COL(X [i]は、Y [i])と== 3)OU [I] = で [ I] = ++ CC; そう であれば(COL(X [i]は、Y [I])== 4)における [I] = ++ CC、OU [I] = ++ CC、G.add_edge(で[ i]は、OU [I]、Z [i])と、 それ以外の 場合(COL(X [i]は、Y [i])と== 1)における [I] = ++ CC、OU [I] = ++ CC 、G.add_edgeは(中[I]、OU [I]、Z [i])と、 それ以外の 場合(COL(X [i]は、Y [i])と== 2)[I] = OU に [I] = ++ CC; S [make_pair(X [i]は、Y [I])] = I; } 用(RI i = 1 ; I <= N; iは++ ){ 場合(COL(X [i]は、Y [i])と== 3)G.add_edge(S、で[I]、Z [I])。 そう であれば(COL(X [i]は、Y [i])と== 2 )G.add_edge(OU [i]は、T、Z [I])。 } int型の PE [ 5 ]。 PE [ 3 ] = 4。PE [ 4 ] = 1。PE [ 1 ] = 2 ; 用(RI I = 1 iが++; iが<= n)の場合(!COL(X [i]は、Y [I])= 2 ){ 用(ロードアイランドJ = 0 ; J < 4; J ++ ){ int型 NX = X [I] + DX [J]、NY = Y [I] + DY [J]。 INT T = S [make_pair(NX、NY)]。 もし(tは> = 1 && T <= N && COL(NX、NY)== PE [COL(X [i]は、Y [I])])G.add_edge(OU [I] で[T]、 INF); } } COUT << G.dinic()<< ENDL。 }