代码
//首先init,传进去的参数分别是两边的点的个数,然后调用solve,如果是求 //最小值,改为负数,相当于的求负数的最大值。 struct KM { int W[maxn][maxn],n,m; int Lx[maxn],Ly[maxn]; int To[maxn]; bool S[maxn],T[maxn]; void init(int nn,int mm) { n=nn; m=mm; memset(To,-1,sizeof(To)); for(int i=1;i<=n;i++) //下标要从1开始 { Lx[i]=Ly[i]=0; for(int j=1;j<=m;j++) Lx[i]=max(Lx[i],W[i][j]); } } bool Match(int u) { S[u]=true; for(int v=1;v<=m;v++) if(Lx[u]+Ly[v]==W[u][v]&&!T[v]) { T[v]=true; if(To[v]==-1||Match(To[v])) { To[v]=u; return true; } } return false; } void Update() { int a=INF; for(int i=1;i<=n;i++) { if(!S[i]) continue; for(int j=1;j<=m;j++) if(!T[j]) a=min(a,Lx[i]+Ly[j]-W[i][j]); } for(int i=1;i<=n;i++) if(S[i]) Lx[i]-=a; for(int i=1;i<=m;i++) if(T[i]) Ly[i]+=a; } int solve() { for(int i=1;i<=n;i++) { while(true) { for(int j=1;j<=m;j++) S[j]=T[j]=0; if(Match(i)) break; Update(); } } int ret=0; for(int i=1;i<=m;i++) if(To[i]!=-1) ret+=W[To[i]][i]; return ret; } }km;