# Include <queue> # include <algorithm> /***************************** *************************** // These are the KM template const int n = 305; // The maximum number of points in each subgraph in the bipartite graph. Const int INF = 1 <28; // positive infinity bool xckd [N], yckd [N]; // In a DFS, whether XI and Yi are on the staggered tree int N; // The case of point int edge [N] [N]; // The Binary Protection value information is stored in the matrix int xmate [N], ymate [N]; // Save the matching result int lx [N], Ly [N]; // XI and Yi and the number, that is, a [] and B [] int slack [N] in the commentary; // relaxation quantity int Prev [N]; //? Queue <int> q; bool BFS (); // find the augmented path void agument (INT); int kmmatch (); // km Algorithm /*************************************** * *****************/Bool BFS () {While (! Q. empty () {int P = Q. front (), u = P> 1; q. pop (); If (P & 1) {If (ymate [u] =-1) {agument (U); Return true ;} else {xckd [ymate [u] = true; q. push (ymate [u] <1) ;}} else {for (INT I = 0; I <n; I ++) {If (yckd [I]) continue; else if (LX [u] + ly [I]! = Edge [u] [I]) {int EX = Lx [u] + ly [I]-edge [u] [I]; If (Slack [I]> ex) {slack [I] = ex; Prev [I] = u ;}} else {yckd [I] = true; Prev [I] = u; q. push (I <1) | 1) ;}}} return false;} void agument (INT U) {While (u! =-1) {int Pv = xmate [Prev [u]; ymate [u] = Prev [u]; xmate [Prev [u] = u; U = PV ;}} int kmmatch () {int I, j, Mn; memset (ly, 0, sizeof (ly); for (I = 0; I <N; I ++) {lx [I] =-INF; For (j = 0; j <n; j ++) {lx [I] = Lx [I]> edge [I] [J]? Lx [I]: edge [I] [J] ;}} memset (xmate,-1, sizeof (xmate); memset (ymate,-1, sizeof (ymate); bool AGU = true; For (Mn = 0; Mn <n; Mn ++) {If (AGU) {memset (xckd, 0, sizeof (xckd); memset (yckd, 0, sizeof (yckd); for (I = 0; I <n; I ++) slack [I] = inf; while (! Q. empty () Q. pop (); xckd [Mn] = true; q. push (Mn <1) ;}if (BFS () {AGU = true; Continue ;}int EX = inf; Mn --; AGU = false; for (I = 0; I <n; I ++) if (! Yckd [I]) EX = ex <slack [I]? Ex: slack [I]; for (I = 0; I <n; I ++) {If (xckd [I]) lx [I]-= ex; if (yckd [I]) ly [I] + = ex; slack [I]-= ex;} for (I = 0; I <n; I ++) if (! Yckd [I] & slack [I] = 0) {yckd [I] = true; q. push (I <1) | 1) ;}} int cost = 0; for (I = 0; I <n; I ++) cost + = edge [I] [xmate [I]; return cost ;}