[Cpp]
/*
N * M rectangle, which is filled with a small rectangle of 1*2. The black part cannot be filled.
Question: Maximum match of black and white games
Set I + j in the board to an odd number as A set, an even number as B sets, and an adjacent number as A link. Then it is converted to the biggest matching problem.
*/
# Include <iostream>
# Define re (I, n) for (int I = 0; I <n; ++ I)
Using namespace std;
Const int nmax= 105;
Const int mMax = 10010;
Int N, M, K;
Int map [nMax] [nMax]; // store the data in the graph
Int G [mMax] [5]; // G [k] [] indicates the padding point connected to k = I * M + j, and the relationship between the AB set is established in the adjacent table.
Int link [mMax];
Int useif [mMax];
Int num; // The maximum number of matches.
Int V; // N * M: Total number of nodes
Void buildGraph () // create a graph to process G
{
Memset (G,-1, sizeof (G ));
Re (I, N) re (j, M)
{
Int u = I * M + j;
Int v = 0;
If (! Map [I] [j] & (I + j) & 1) = 1) // this point can be filled with an odd number of I + j
{
// Left
If (j> 0 &&! Map [I] [j-1])
{
G [u] [v ++] = u-1;
}
// Right
If (j <M-1 &&! Map [I] [j + 1])
{
G [u] [v ++] = u + 1;
}
// Upload
If (I> 0 &&! Map [I-1] [j])
{
G [u] [v ++] = u-M;
}
// Lower
If (I <N-1 &&! Map [I + 1] [j])
{
G [u] [v ++] = u + M;
}
}
}
}
Int dfs (int t)
{
For (int I = 0; G [t] [I]! =-1; ++ I)
{
Int u = G [t] [I];
If (! Useif [u]) // because of the structure of the adjacent table, t and u must be correlated. You do not need to make a map [] [] Judgment.
{
Useif [u] = 1; www.2cto.com
If (link [u] =-1 | dfs (link [u])
{
Link [u] = t;
Return 1;
}
}
}
Return 0;
}
Int maxMatch ()
{
Num = 0;
Memset (link,-1, sizeof (link ));
Re (I, V)
{
Memset (useif, 0, sizeof (useif ));
If (dfs (I ))
Num ++;
}
Return num;
}
Int main ()
{
// Freopen ("f: // data. in", "r", stdin );
While (scanf ("% d", & N, & M )! = EOF)
{
If (! N &&! M) break;
Scanf ("% d", & K );
Memset (map, 0, sizeof (map ));
Re (I, K)
{
Int a, B;
Scanf ("% d", & a, & B );
Map [a-1] [B-1] = 1;
}
V = N * M;
BuildGraph ();
MaxMatch ();
Printf ("% d \ n", num );
Re (I, V)
{
If (link [I]! =-1) // because of the maximum match, there will be no duplicates. Search once and then output
{
Int u = link [I];
Printf ("(% d, % d) -- (% d, % d) \ n", u/M + 1, u % M + 1, I/M + 1, I % M + 1 );
}
}
Printf ("\ n ");
}
Return 0;
}
Author: lhshaoren