Description
Input
Output
Sample Input
2 100 10 15 23
Sample Output
123
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define maxn 505 #define inf 0x3f3f3f3f typedef long long ll; int g[maxn][maxn]; int link[maxn],lx[maxn],ly[maxn],slack[maxn]; bool s[maxn],t[maxn]; int n; bool dfs(int i){ s[i]=1; for(int j=1;j<=n;j++){ if(!t[j]){ int temp=lx[i]+ly[j]-g[i][j]; if(temp==0){ t[j]=1; if(link[j]==-1||dfs(link[j])){ link[j]=i; return true; } } else{ slack[j]=min(temp,slack[j]); //这里的slack保证了是s[]和!t[]的 } } } return false; } void update(){ int a=inf; for(int i=1;i<=n;i++){ if(!t[i])a=min(a,slack[i]); } for(int i=1;i<=n;i++){ if(s[i])lx[i]-=a; if(t[i])ly[i]+=a; } } int km(){ for(int i=1;i<=n;i++){ lx[i]=ly[i]=0;link[i]=-1; for(int j=1;j<=n;j++){ lx[i]=max(lx[i],g[i][j]); } } for(int i=1;i<=n;i++){ memset(slack,inf,sizeof slack); while(true){ for(int j=1;j<=n;j++)s[j]=t[j]=0; if(dfs(i))break; else update(); } } int ans=0; for(int i=1;i<=n;i++){ if(link[i]!=-1)ans+=g[link[i]][i]; //因为权值是从左到右的,而link记录的是i的匹配边。 } return ans; } int main() { //freopen("in.txt","r",stdin); while(~scanf("%d",&n)){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ scanf("%d",&g[i][j]); } } int res=km(); printf("%d\n",res); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u013497977/article/details/47722999