The main idea: to find the best matching of the two graphs (the first number is the largest, followed by the largest weight).
Key to problem solving: km algorithm
Complexity: $O (n^3) $
#include <cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<iostream>#include<cmath>using namespaceStd;typedefLong Longll;Const intn=310;Const intinf=0x3f3f3f3f;intNx,ny;intG[n][n];intMatch[n],lx[n],ly[n];//points in Y match state, vertex labels in x, yintSlack[n];BOOLVisx[n],visy[n];BOOLHungry (intx) {Visx[x]=1; for(inty=1; y<=ny; y++){ if(Visy[y])Continue; inttmp=lx[x]+ly[y]-G[x][y]; if(tmp==0) {Visy[y]=true; if(match[y]==-1||hungry (Match[y])) {Match[y]=x; return 1; } } Else if(slack[y]>tmp) slack[y]=tmp; } return 0;}intKM () {memset (match,-1,sizeofmatch); memset (ly,0,sizeofly); for(intI=1; i<=nx;i++) {Lx[i]=-inf; for(intj=1; j<=ny;j++) lx[i]=Max (lx[i],g[i][j]); } for(intx=1; x<=nx;x++){ for(intI=1; i<=ny;i++) slack[i]=inf; while(1) {memset (VISX,0,sizeofVISX); memset (Visy,0,sizeofVisy); if(Hungry (x)) Break; intD=inf; for(intI=1; i<=ny;i++)if(!visy[i]&&d>slack[i]) d=Slack[i]; for(intI=1; i<=nx;i++)if(Visx[i]) lx[i]-=D; for(intI=1; i<=ny;i++){ if(Visy[i]) ly[i]+=D; Elseslack[i]-=D; } } } intres=0; for(intI=1; i<=ny;i++) if(match[i]!=-1) res+=G[match[i]][i]; returnRes;}intMain () {intN; while(~SCANF ("%d",&N)) { for(intI=1; i<=n;i++) for(intj=1; j<=n;j++) scanf ("%d",&G[i][j]); NX=ny=N; printf ("%d\n", KM ()); } return 0;}
[hdu2255] Ben-well-off make a lot of money (binary graph optimal matching, km algorithm)