题目来源:http:/showproblem.php?pid=2255
题意
中文题意,,,,
思路
这道题是一道模板题。。。
贴上两篇博客,内容是 循序渐进。,。。
no1:http://www.cnblogs.com/wenruo/p/5264235.html
no2:http://dsqiu.iteye.com/blog/1689505
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=300+10;
const int INF=0x3f3f3f3f;
int pre[maxn],vis1[maxn],vis2[maxn];
int mp[maxn][maxn],ex1[maxn],ex2[maxn],slack[maxn];
int n;
void init()
{
memset(ex1,0,sizeof(ex1));
memset(ex2,0,sizeof(ex2));
for(int i=1; i<=n; i++)
{
ex2[i]=0;
for(int j=1; j<=n; j++)
{
scanf("%d",&mp[i][j]);
ex1[i]=max(ex1[i],mp[i][j]);
}
}
}
bool dfs(int i)
{
vis1[i]=1;
for(int j=1; j<=n; j++)
{
if(!vis2[j])
{
int dx=ex1[i]+ex2[j]-mp[i][j];
if(dx==0)
{
vis2[j]=1;
if(pre[j]==-1||dfs(pre[j]))
{
pre[j]=i;
return true;
}
}
else
{
slack[j] = min(slack[j],dx);
}
}
}
return false;
}
void solve()
{
memset(pre,-1,sizeof(pre));
for(int i=1; i<=n; i++)
{
fill(slack+1,slack+n+1,INF);//为了快速找到2最少需要多少才可以满足
while(1)
{
memset(vis1,0,sizeof(vis1));
memset(vis2,0,sizeof(vis2));
if(dfs(i)) break;
int d=INF;
for(int j=1; j<=n; j++)
{
if(!vis2[j])
d=min(d,slack[j]);
}
for(int j=1; j<=n; j++)
{
if(vis1[j])
ex1[j]-=d;
if(vis2[j])
ex2[j]+=d;
else
slack[j]-=d;
}
}
}
int ret=0;
for(int i=1; i<=n; i++)
{
ret+=mp[pre[i]][i];
}
printf("%d\n",ret);
}
int main()
{
while(~scanf("%d",&n))
{
init();
solve();
}
}