Theme:
In the space of N * n, there are K minor planets. Using super weapons, you can clean up one row or one column of all minor planets at a time. however, the super weapon is very expensive. The sky chart is displayed, and the minimum number of weapons required to be used can clear all the minor planets. n <500, k <10,000
Analysis:
Classic lineColumn model conversionForBipartite Graph ModelZju1002 and pku2226 can also be converted.
Use rows and columns as the nodes on the left and right of the Bipartite Graph. if there is an minor on the map (I, j), an edge is connected between the I node on the left and J node on the right of the Bipartite Graph.
When this model is mapped to the question, a weapon is used to select a vertex V on the left or right of the Bipartite Graph. the edge connected to V indicates all the minor planets in the V row (or column. the question is converted to: select the least vertex in the bipartite graph, so that at least one endpoint of all edges is overwritten.
This is the classic bipartite graph.Minimum point coverage.
AccordingKönig Theorem: Bipartite GraphMinimum vertex overwrite = maximum number of matches.
Therefore, the question is convertedMaximum matching of a Bipartite Graph, It is a perfect solution.
By the way, the zju1002 bipartite graph model cannot directly use rows or columns as the vertices of the Bipartite Graph, but needsSplit point. For more information, see my other solution report.
Http://blog.csdn.net/tiaotiaoyly/archive/2008/10/23/3122893.aspx
- /*
- Pku3041 Asteroids
- */
- # Include <stdio. h>
- # Include <memory. h>
- # Define CLR (a) memset (A, 0, sizeof ())
- # Define n 505
- Int find (int I, int M, int G [] [N], int mat [], int tmat []) {
- Int V, J;
- For (j = 0; j <m; j ++ ){
- If (G [I] [J] & tmat [J] = 0 ){
- Tmat [J] = 1; V = mat [J]; MAT [J] = I;
- If (V =-1 | find (v, M, G, mat, tmat) return 1;
- Mat [J] = V;
- }
- }
- Return 0;
- }
- Int match (int g [] [N], int N, int M, int mat []) {
- Int I, K = 0, tmat [N];
- For (I = 0; I <m; I ++) mat [I] =-1;
- For (I = 0; I <n; I ++ ){
- CLR (tmat); k + = find (I, m, G, mat, tmat );
- }
- Return K;
- }
- Int n, m;
- Int a [n] [N];
- Int mat [N];
- Int main ()
- {
- Int I, J, K;
- While (scanf ("% d", & N, & M )! = EOF ){
- // Init
- CLR ();
- // Input
- For (k = 0; k <m; k ++ ){
- Scanf ("% d", & I, & J );
- I --; j --;
- A [I] [J] = 1;
- }
- // Output
- K = match (A, N, N, mat );
- Printf ("% d/N", k );
- }
- Return 0;
- }