Title: Give a chessboard, there are some numbers, each can be adjacent to the two number plus one. The minimum number of questions makes the numbers on the board equal.
Idea: The basic idea: the least equal number of two points. The checkerboard black and white staining, each operation will make a sunspot and a white child plus 1, the establishment of a binary map, s to all white dots, all black dots to the t edge, traffic for each point to reach the need for equal number of the size of the demand. Adjacent black and white dots, f:inf. Then run the maximum flow to see if the flow is full.
But the problem needs to be a little more.
The difference between the Suma and the sumb will not change because each time the black and white dots are added to the 1.
If the m*n is an even number, then the black dots are the same, if suma! =sumb is no solution.
If the m*n is an odd number, then O (1) can calculate the feasible equal numbers, and the direct judgment can be solved.
The rest of the situation can prove the correctness of the two points, if it can be equal to K, then cut off a layer will become k-1, because M*n is even, so there must be a scheme cut off a layer.
CODE:
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include < algorithm> #define MAX 2010#define maxe 210010#define S 0#define T (MAX-1) #define INF (1ll <<) using namespace std;const int dx[] = {0,1,-1,0,0};const int dy[] = {0,0,0,1,-1};long long all_flow;struct maxflow{int head[max],total;int Next[maxe],aim[maxe];long Long Flow[maxe];int deep[max];void Reset () {total = 1;memset (head,0,sizeof (Head));} void Add (int x,int y,long long f) {next[++total] = head[x];aim[total] = Y;flow[total] = f;head[x] = total;} void Insert (int x,int y,long long f) {if (x = = S) All_flow + = f; ADD (X,Y,F); ADD (y,x,0);} BOOL BFS () {static queue<int> Q;while (!q.empty ()) Q.pop () memset (deep,0,sizeof (deep));d eep[s] = 1;q.push (S); while (!q.empty ()) {int x = Q.front (), Q.pop (), for (int i = head[x]; i; i = Next[i]) if (Flow[i] &&!deep[aim[i]) {de Ep[aim[i]] = deep[x] + 1;q.push (Aim[i]), if (aim[i] = = T) return true;}} return false;} Long long dinic (int x,long loNg f) {if (x = = T) return f;long Long temp = f;for (int i = head[x]; i; i = Next[i]) if (flow[i] && temp && Dee P[aim[i]] = = Deep[x] + 1) {long Long away = Dinic (Aim[i],min (flow[i],temp)); if (!away) deep[aim[i]] = 0;flow[i]-= Away;flow [i^1] + = away;temp-= away;} return f-temp;}} Solver;int _t,m,n,cnt;int src[50][50],num[50][50];bool Color[50][50];long long black,white,start;int b_cnt,w_cnt; inline void Initialize () {black = white = CNT = 0;b_cnt = w_cnt = 0;start = 0;memset (color,0,sizeof (color)); Memset (Num,0,si Zeof (num)); color[1][1] = true;for (int i = 2; I <= m; ++i) color[i][1] =!color[i-1][1];for (int i = 1; I <= m; ++i) F or (int j = 2; J <= N; ++j) color[i][j] =!color[i][j-1];} inline bool Judge (long long ans) {solver. Reset (); all_flow = 0;for (int i = 1; I <= m; ++i) for (int j = 1; j <= N; ++j) color[i][j]? Solver. Insert (S,num[i][j],ans-src[i][j]): Solver. Insert (Num[i][j],t,ans-src[i][j]), for (int i = 1, i <= m; ++i) for (int j = 1; j <= N; ++j) {if (!colorI [j]) continue;for (int k = 1; k <= 4; ++k) {int FX = i + dx[k],fy = j + dy[k];if (!fx | |!fy | | FX > M | | fy > N) continu E;solver. Insert (Num[i][j],num[fx][fy],inf);}} Long Long Max_flow = 0;while (solver. BFS ()) Max_flow + = Solver. Dinic (S,inf); return max_flow = = All_flow;} int main () {for (CIN >> _t; _t--;) {scanf ("%d%d", &m,&n); Initialize (); for (int i = 1; I <= m; ++i) for (int j = 1; j <= N; ++j) {scanf ("%d", &SR C[I][J]), num[i][j] = ++cnt;start = Max (start, (long Long) src[i][j]);} for (int i = 1, i <= m; ++i) for (int j = 1; j <= N; ++j) {Color[i][j]? white + = Src[i][j]:black + = Src[i][j];color[i] [j]? ++w_cnt:++b_cnt;} if (w_cnt! = b_cnt) {Long Long mid = (black-white)/(B_CNT-W_CNT), if (Mid >= start && Judge (mid)) printf ("%ll D\n ", ((Long Long) m * n * mid-white-black) >> 1); Elseputs (" 1 ");} else {if (black! = white) {puts ("-1"); continue;} Long long L = start,r = Inf,ans = -1;while (l <= R) {Long Long mid = (L + R) >> 1;if (Judge (mid)) r= Mid-1,ans = Mid;elsel = mid + 1;} if (ans + 1) printf ("%lld\n", (ANS * m * n-white-black) >> 1); Elseputs ("1");}} return 0;}
Bzoj 2756 Scoi 2012 Strange Game two points + Max stream