Article From:https://www.cnblogs.com/maomao9173/p/9971283.html

There is one\(n\)That’s ok\(m\)The black-and-white chessboard of the column, you can exchange the chessboard in two adjacent lattices (adjacent refers to having common edges or common vertices) at a time, and finally reach the goal state. Request No.\(i\)Xing di\(j\)The lattice of a column can only participate\(m[i][j]\)Secondary exchange.

Input Format:

The first line contains two integers\(n,m(1<=n, m<=20)\)

Following\(n\)Behavior Initial State, Each Behavior Includes One\(m\)Character\(01\)String, of which\(0\)Represents a black chess piece.\(1\)Represents a white chess piece.

Following\(n\)Behavior target state in the same format as the initial state.

Following\(n\)A row contains one for each action\(m\)individual\(0-9\)A string of numbers representing the upper limit of the number of times each lattice participates in the exchange.

Output Format:

The output is only one line, which is the minimum total number of swaps. If there is no solution, output\(-1\)

Input sample #1:

3 3
110
000
001
000
110
100
222
222
222

Output sample #1:

4

The solution of this problem is to let the beginner like me learn network flow. (Beginner OI)People can understand, if there are still doubts, please contact me.

\(1\),However, for intermediate nodes, the consumption of traffic should be\(2\)。If we simply consider splitting a point into one side, we can’t deal with this kind of boundary situation, and things will become relatively troublesome.

\(3\)One:\(inn\)\(mid\)and\(out\),Divide the original maximum traffic on both ends, and consider each incoming and outgoing traffic as\(1\)。At the same time, it solves the problem of entering and leaving the chessboard: directly in\(mid\)You don’t have to think about other troublesome things when you go to the chessboard.

then traffic equalization is possible.Is the idea right? Basically right. But now we have\(inn\)->\(mid\)and\(mid\)->\(out\)Two sides, if the edge weight is odd, the flow required to enter and exit the chessboard is only for\(1\),A fraction that should not have been overlooked\(1\)It may be neglected or not optimally allocated.

So here is the problem of dealing with this boundary. If the chessboard begins and endsIf we have or don’t have the chess pieces, then we have the right to use them.\(maxf\)take\(1/2\)。Otherwise, consider the situation of entering and going out separately:

As you can see, when entering\(mid\)->\(out\),When going out\(inn\)->\(mid\)There will be a drain.\(1\)On the edge, we consider that if this point is not both in and out of the node, it exists.\(1\)Part of the consuming edge tries to allocate a little more “zero” traffic (i.e., even-numbered traffic).\(n/2\)or\((n+1)/2\)It’s the same, and odd numbers are assigned to\(n/2\)\((n+1)/2\)。)

In order to help you sort out the ideas, here I paste the drawing process:

  • Initial point – & gt;\(S\) \(f=1\) \(w=0\)
  • Final point & lt;-\(T\) \(f=1\) \(w=0\)
  • Initial point – & gt; corresponding coordinates\(mid\)node\(f=1\) \(w=0\)
  • Corresponding coordinates\(mid\)Node – & gt; termination point\(f=1\) \(w=0\)
  • The eight links in the chessboard: (1)\(out\)->\(in\)) \(f=INF\) \(w=1\)
  • \(inn\)->\(mid\)and\(mid\)->\(out\)\(w=1\),Confirm the choice according to the situation\(f=maxf/2\) perhaps\(f=(maxf+1)/2\)

#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 2010 #define MAXM 64010 #define INF 0x3f3f3f3f #define fpop(x) x.front();x.pop() using namespace std; int pre_node[MAXN],pre_edge[MAXN]; char ch,mp_bg[25][25],mp_ed[25][25]; int n,m,cnt=-1,dis[MAXN],vis[MAXN],flow[MAXN],head[MAXN],maxf[25][25]; struct edge{ int nxt,to,w,f; }e[MAXM]; inline int _bg(int x,int y){return n*m*0+(x-1)*m+y;}//Number of starting point [x, y]Inline int_ed(int x, int y){return n*m*1+(x-1)*m+y;}// Number of target point [x, y]Inline int_inn(int x)Inn point number of {return n*m*2+(x-1)*m+y;}//chessboard [x,y]Inline int_mid(int x, int y){return n*m*3+(x-1)*m+Midpoint labeling of y;}//chessboard [x, y]The Out Point Number of inline int_out(int x,int y){return n*m*4+(x-1)*m+y;}//chessboard [x,y]Inline BOol in_map (int x, int y) {Return 1 & lt; = x & amp; & amp; X & lt; = n & amp; & amp; 1 & lt; = y & amp; & amp; Y & lt; = m;}// Judging whether or not the boundary is crossedInline void add_edge (int from, int to, int flw, int val) {E [++ cnt]. NXT = head [from];E [cnt]. to = to;E[cnt]. f = flw;E[cnt]. w = val;Head [from] = cnt;}Queue & lt; int & gt; que;InlIne bool SPFA (int s, int t) {Memset (vis, 0, sizeof (vis));Memset (dis, 0x3f, sizeof (dis));MEMSet (flow, 0x3f, sizeof (flow));Que. push (s); vis [s] = true; dis [s] = 0;While (! Que. empty (){Int u = fpop (que);For (int I = head [u]; ~i; I = e [i]. nxt) {Int v = e [i].to;I f (dis [v] & gt; dis [u] + e [i]. W & amp; & amp; e [i]. f) {Dis [v] = dis [u] + e [i]. w;Flow [v] = min (flow [u], e [i], f);Pre_node [v]= u;Pre_edge [v]= i;Vis [v] = true; que. push (v);}}}Return dis [t]!= INF;}Int mv[8][2]={1,0}, {-1,0}, {0,1}, {0,-1}, {1,1}, {1,-1}, {1,-1}, {-1,1}, {-1,-1};Int main () {Memset (head, -1, sizeof (h)EAD);Scanf ("% d% d", & amp; n, & amp; m);For (int I = 1; I & lt; = n; ++ i) {For (int J = 1; J & lt; = m; +)J) {Scanf ("% c", & amp; mp_bg [i] [j]);}}For (int I = 1; I & lt; = n; ++ i) {For (int J = 1; J & lt; = m; + + j) {Scanf ("% c", & amp; mp_ed [i] [j]);}}For (int i=)1; i< = n; ++ i) {For (int J = 1; J & lt; = m; + + j) {Scanf ("% c", & amp; ch);MAXF[i] [j] = ch-'0';// Maximum number of passes}}// Input Start and Target Chess BoardInt s = 0, t = n * m * 5 + 1;InT cnt_1 = 0, cnt_2 = 0;For (int I = 1; I & lt; = n; ++ i) {For (int J = 1; J & lt; = m; + + j) {If (MP)_ BG [i] [j]==mp_ed [i] [j] {Add_edge(_inn(i,j), _mid(i,j), maxf[i][j]/2,0);Add_edge(_mid(i,j), _inn(i,j), 000000000,0);Add_edge(_mid(i, j),_out(i,j), maxf[i][j]/2,0;Add_edge(_out(i,j), _mid(i,j), 000000000,0);}else{If (mp_bg [i] [j]=='1') {Add_edge(_inn(i,j), _mid(i,j), (max)F [i] [j] + 0) / 2,0;Add_edge(_mid(i,j), _inn(i,j), 000000000,0);Add_edge(_mid(i,j), _out(i,j), (maxf[i][j]+1)/2,0);Add_edGe(_out(i,j), _mid(i,j), 000000000000,0);}If (mp_ed[i] [j]=='1') {Add_edge(_inn(i,j), _mid(i,j), (maxf[i][j]+1)/2,0);Add_edge(_mid)I, j), _inn (i, j), 000000000000,0;Add_edge(_mid (i, j), _out (i, j)(maxf [i] [j] + 0)/2,0);Add_edge(_out(i,j), _mid(i,j), 000000000,0);}}If (mp_bg [i] [j]=='1') {++cnt_1;// Connect the source point to the initial point F = 1 W = 0;Add_edge (s, _bg (i, j), 1,0);Add_edge (_ BG (i, j), s, 0, 0);//Connect the starting point to the chessboardAdd_edge(_bg (i, j), _mid (i, j), 1,0);Add_edge(_mid(i,j), _bg(i,j), 0,0);}If (mp_ed[i] [j]=='1') {++cnt_2;// Connection endpoint to sink f = 1 W = 0;Add_edge(_ed (i, j), t, 1, 0);Add_edge (t, _ed (i, j), 0, 0);//Connect the chessboard to the endpointAdd_edge(_mid)(i, j), _ed (i, j), 1,0);Add_edge(_ed (i, j), _mid (i, j), 0, 0);}/ / chessThe eight connected edges of a disk f = INF w = 1;For (int k = 0; K & lt; 8; + + k) {Int Ni = I + MV [k] [0];Int NJ = j + MV [k] [1];If (in_map (ni, nj){// Out Connection Point of Slave Point [i, j] [ni]Nj]'s InnAdd_edge(_out (i, j), _inn (ni, nj), INF, +1);Add_edge (Inn (ni, nj), _out (i, j), 000, -1;}}}}// Chess Number Change - & gt; No solUtionIf (cnt_1!= cnt_2) {Puts ("-1");Return 0;}// Then run the expense streamInt max_fLow = 0, min_cost = 0;While (spfa (s, t){Max_flow+= flow [t];Min_cost+= flow [t] * dis [t];Int u=t;While (U! =s) {E [pre_edge [u] ^ 0]. F - = flow [t];E[pre_edGe [u] ^ 1]. F + = flow [t];U = pre_node [u];}}If (max_flow!= cnt_1) {PutS ("-1");Return 0;}Printf ("% d n", min_cost);}

Leave a Reply

Your email address will not be published. Required fields are marked *