Lightoj1011【KM算法】
题意:
问男孩女孩最大的可能值?其实就是一个二分图的最大权值匹配问题;模板题吧。。
#include<cstdio> #include<math.h> #include<queue> #include<map> #include<string> #include<string.h> #include<iostream> #include<algorithm> using namespace std; typedef long long LL; const int INF=0x3f3f3f3f; const LL mod=1e9+7; const int N=20; int ma[N][N]; int lx[N],ly[N],match[N]; bool vx[N],vy[N]; int n,d; bool Findpath(int u) { vx[u]=1; for(int i=1;i<=n;i++) { if(vy[i]) continue; int temp=lx[u]+ly[i]-ma[u][i]; if(temp==0) { vy[i]=1; if(match[i]==-1||Findpath(match[i])) { match[i]=u; return true; } } else if(d>temp) d=temp; } return false; } int KM() { memset(match,-1,sizeof(match)); memchr(lx,0,sizeof(lx)); memset(ly,0,sizeof(ly)); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) lx[i]=max(lx[i],ma[i][j]); for(int i=1;i<=n;i++) { while(1) { memset(vx,0,sizeof(vx)); memset(vy,0,sizeof(vy)); d=INF; if(Findpath(i)) break; for(int j=1;j<=n;j++) { if(vx[j]) lx[j]-=d; if(vy[j]) ly[j]+=d; } } } int res=0; for(int i=1;i<=n;i++) res+=ma[match[i]][i]; return res; } int main() { int cas=1,T; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { scanf("%d",&ma[i][j]); } printf("Case %d: ",cas++); printf("%d\n",KM()); } return 0; }