hdu-2255(带权二分图)
题解:板子题。。。。
#include<iostream> #include<cstring> #include<cstdio> #include<queue> #include<algorithm> #define maxn 1005 #define inf 0x3f3f3f3f using namespace std; int ex_l[maxn]; int ex_r[maxn]; bool visit_l[maxn]; bool visit_r[maxn]; int match[maxn]; int e[maxn][maxn]; int slack[maxn]; int n,m; int x,y,w; bool dfs(int l) { visit_l[l]=true; for(int r=n+1;r<=2*n;r++) { if(visit_r[r]==true) continue; int v=ex_l[l]+ex_r[r]-e[l][r]; if(v==0) { visit_r[r]=true; if(match[r]==-1||dfs(match[r])) { match[r]=l; return true; } } else slack[r]=min(slack[r],v); } return false; } int km() { memset(match,-1,sizeof(match)); memset(ex_r,0,sizeof(ex_r)); for(int l=1;l<=n;l++) { ex_l[l]=0; for(int r=n+1;r<=2*n;r++) { ex_l[l]=max(ex_l[l],e[l][r]); } } for(int l=1;l<=n;l++) { memset(slack,inf,sizeof(slack)); while(1) { memset(visit_l,0,sizeof(visit_l)); memset(visit_r,0,sizeof(visit_r)); if(dfs(l)) break; int d=inf; for(int r=n+1;r<=2*n;r++) { if(!visit_r[r]) d=min(d,slack[r]); } for(int k=1;k<=n;k++) { if(visit_l[k]) ex_l[k]-=d; if(visit_r[k+n]) ex_r[k+n]+=d; else slack[k+n]-=d; } } } int ans=0; for(int i=n+1;i<=2*n;i++) { ans+=e[match[i]][i]; } return ans; } int main() { while(scanf("%d",&n)!=EOF) { memset(e,0,sizeof(e)); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { scanf("%d",&x); e[i][j+n]=x; } } printf("%d\n",km()); } return 0; }