First Orz litble--km algorithm
Why use the KM algorithm
Because some of the problem of insane card fee flow
The KM algorithm has higher efficiency than the cost flow.
Algorithmic flow
We set an expectation "feasible top mark" for each point.
For the point on the left, the point that is expected to match to the right of the multi-power value
For the point on the right, it is how much you expect to be able to contribute to the expectations on the left side.
Two points can match, when and only if the sum of their expected value is the weight of the edge
The expectation of initializing all left points at the beginning is the maximum value of their out-of-the-edges, because ideally, each point matches the one that matches the maximum.
The right point is expected to be 0
Then we matched each other, and when a point match failed, all the left-hand expectations were too high.
We find the least desired point from the mismatched point in the right point, the left point of all the matches involved minus this expectation "so that the matching point is one more", and then its matching right point to add this expectation "because also to ensure that the matching points can still be matched"
Then continue to try to match
Until all points have been matched.
Board:
#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>#define LL Long Long int#define Redge (U) for (int k = h[u],to; k; k = ed[k].nxt)#define REP (i,n) for (int i = 1; I <= (n); i++)#define BUG (s,n) for (int i = 1; I <= (n); i++) cout<<s[i]<< '; puts ("");using namespaceStdConst intMAXN =405, MAXM =100005, INF =1000000000;inline intRead () {intout =0, flag =1;Charc = GetChar (); while(C < -|| C > $){if(c = ='-') flag =-1; c = GetChar ();} while(c >= -&& C <= $) {out = (out <<3) + (out <<1) + C- -; c = GetChar ();}returnOut * FLAG;}intW[MAXN][MAXN],EXPA[MAXN],EXPB[MAXN],VISA[MAXN],VISB[MAXN],CP[MAXN],DL[MAXN];intNBOOLDfsintu) {Visa[u] =true; REP (I,n)if(!visb[i]) {intKL = Expa[u] + expb[i]-w[u][i];if(KL = =0) {Visb[i] =true;if(!cp[i] | | DFS (CP[I)) {Cp[i] = u;return true; } }ElseDl[i] = min (DL[I],KL); }return false;}intSolve () {REP (i,n) expa[i] = expb[i] = Cp[i] =0; Rep (I,n) Rep (j,n) expa[i] = max (expa[i],w[i][j]); Rep (I,n) {rep (j,n) dl[j] = INF; while(true) {REP (j,n) visa[j] =false, visb[j] =false;if(Dfs (i)) Break;intKL = INF; REP (J,n)if(!visb[j]) kl = MIN (kl,dl[j]); REP (j,n) {if(Visa[j]) expa[j]-= KL;if(Visb[j]) expb[j] + = KL;ElseDL[J]-= KL; } } }intRe =0; REP (i,n) Re + = W[cp[i]][i];returnRe;}intMain () {n = read (); Rep (I,n) Rep (j,n) w[i][j] = read (); printf"%d\n", solve ());return 0;}
KM algorithm "with weighted binary graph perfect Match"