最大匹配 && 最佳完美匹配 模板
1.最佳完美匹配------km算法
bool match(int u){ s[u]=true; for(int v=1; v<=n; v++){ if(t[v]) continue; int d=lx[u]+ly[v]-w[u][v]; if(!d){ t[v]=true; if(lft[v]==-1 || match(lft[v])){ lft[v]=u; return true; } } else slack[v]=MIN(slack[v], d); } return false; } int km(){ int i, j; fill(lft+1, lft+1+n, -1); fill(ly+1, ly+1+n, 0); for(i=1; i<=n; i++) for(j=1, lx[i]=-INF; j<=n; j++) lx[i]=MAX(lx[i], w[i][j]); for(i=1; i<=n; i++){ fill(slack+1, slack+1+n, INF); while(true){ fill(s+1, s+1+n, 0); fill(t+1, t+1+n, 0); if(match(i)) break; int d=INF; for(j=1; j<=n; j++) if(!t[j]) d=MIN(d, slack[j]); for(j=1; j<=n; j++){ if(s[j]) lx[j]-=d; if(t[j]) ly[j]+=d; // else slack[j]-=d; } } } int ans=0; for(i=1; i<=n; i++) ans+=w[lft[i]][i]; return ans; }
2.最大匹配------匈牙利算法 (Hungary Algorithm by Edmonds)
bool match(int u){ //最大匹配 for(int i=0; i<g[u].size(); i++){ int v = g[u][i]; if(vis[v]) continue; vis[v]=true; if(lft[v]==-1 || match(lft[v])){ lft[v]=u; return true; } } return false; } int solve(){ int ans=0; fill_n(lft+1, v, -1); for(i=0; i<votedog.size(); i++){ fill_n(vis+1, v, false); if(match(votedog[i])) ans++; } return v-ans; }