Main topic
Gives a nxnxn Matrix, each block on the matrix can be painted in two colors, and the adjacent two squares will produce a little energy if they are painted in different colors. Now that you know the color of some squares, ask how much energy you can generate.
Ideas
Assume that all adjacent blocks generate energy, and do not take into account the already good color of the block, then minus the illegal on the line.
In general, what happens between the adjacent blocks is that all points are dyed, one color is connected to s, and the other is connected to T. In this problem, the left side of the point if the end belongs to the S set, representing the point on the P-color, otherwise on the N-color, the right point if the end belongs to the T set, representing the point on the P-color, otherwise on the N-color. In the final answer, we only record how many n colors surround the P-color, not how many p-colors surround the N-color.
Because now we're assuming that all the blocks are generating energy, so the flow from S to all the left points is the number of adjacent points around the point, the same as the point on the right. If a point is not a P-color, then it loses all energy (because only the energy generated by the P-color is recorded).
If the left and right points are not in the same set (that is, the edges between them are cut off), then their final color is the same, so no energy is generated, and the left and right sides are reduced by 1, so the traffic on this side is 2.
Then run a dinic on the line ...
CODE
#define _crt_secure_no_warnings#include <queue>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAX#define MAXP (max * max * max)#define Maxe 1000010#define INF 0x3f3f3f3f#define S 0#define T (MAXP-1)using namespace STD;#define InRange (x, Y, z) (x * y * z && x <= m && y <= m && z <= m)Const intDx[] = {0,1, -1,0,0,0,0};Const intDy[] = {0,0,0,1, -1,0,0};Const intDz[] = {0,0,0,0,0,1, -1};structmaxflow{intHEAD[MAXP], total;intNext[maxe], Aim[maxe], flow[maxe];intDEEP[MAXP]; Maxflow (): Total (1) {}voidADD (intXintYintf) {Next[++total] = head[x]; Aim[total] = y; Flow[total] = f; HEAD[X] = total; }voidInsert (intXintYintf) {Add (x, Y, F); Add (y, X,0); }BOOLBFS () {Static Queue<int>Q while(!q.empty ()) Q.pop ();memset(Deep,0,sizeof(deep)); Deep[s] =1; Q.push (S); while(!q.empty ()) {intx = Q.front (); Q.pop (); for(inti = head[x]; I i = Next[i])if(Flow[i] &&!deep[aim[i]) {Deep[aim[i]] = deep[x] +1; Q.push (Aim[i]);if(Aim[i] = = T)return true; } }return false; }intDinic (intXintf) {if(x = = T)returnFinttemp = f; for(inti = head[x]; I i = Next[i])if(Flow[i] && deep[aim[i]] = = Deep[x] +1&& temp) {intaway = Dinic (Aim[i], min (flow[i], temp));if(!away) deep[aim[i]] =0; Flow[i]-= away; flow[i^1] + = away; Temp-= away; }returnF-temp; }}solver;intMCharSrc[max][max][max];intNum[max][max][max], CNT;intAnsintMain () {Cin>> m; for(inti =1; I <= m; ++i) for(intj =1; J <= M; ++J)scanf('%s ', Src[i][j] +1); for(inti =1; I <= m; ++i) for(intj =1; J <= M; ++J) for(intK =1; K <= m; ++K) num[i][j][k] = ++cnt; for(inti =1; I <= m; ++i) for(intj =1; J <= M; ++J) for(intK =1; K <= m; ++K) {intnear =0; for(intD =1; D <=6; ++d) {intFX = i + dx[d];intFY = j + dy[d];intFZ = k + dz[d];BOOLFlag = InRange (FX, FY, FZ); near + = Flag;if(Flag && (i + j + k) &1) Solver. Insert (Num[i][j][k], NUM[FX][FY][FZ],2); } ans + = near;if((i + j + k) &1) Solver. Insert (S, Num[i][j][k], near);ElseSolver. Insert (Num[i][j][k], T, near); } for(inti =1; I <= m; ++i) for(intj =1; J <= M; ++J) for(intK =1; K <= m; ++K)if((i + j + k) &1) {if(Src[i][j][k] = =' P ') Solver. Insert (S, num[i][j][k], INF);Else if(Src[i][j][k] = =' N ') Solver. Insert (Num[i][j][k], T, INF); }Else{if(Src[i][j][k] = =' P ') Solver. Insert (Num[i][j][k], T, INF);Else if(Src[i][j][k] = =' N ') Solver. Insert (S, num[i][j][k], INF); }intMax_flow =0; while(Solver. BFS ()) Max_flow + = Solver. Dinic (S, INF);cout<< Ans-max_flow << Endl;return 0;}
Bzoj 1976 BeiJing2010 Team Energy Cube Cube min cut