只有一组测试用例。
输入:第一行是操作员的人数n(4=<n<=11),接下来的n行里每行有n个数,分别表示第i名操作员完成第i项任务的时间。要求每人完成且只完成一项任务。
输出:完成所有任务的最短时间。
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int tt[15][15],cz[15],rw[15],vt1[15],vt2[15],pp[15]; //时间矩阵,操作员顶标,任务顶标,操作员访问,任务员访问,最佳匹配
int n,mt=0,slack;
//km算法实现
int dfs(int i)
{
vt1[i]=1;
for(int j=1;j<=n;j++)
{
if(vt2[j]==0)
{
int t=cz[i]+rw[j]-tt[i][j];
if(t==0)
{
vt2[j]=1;
if( (pp[j]==0) || (dfs(pp[j])))
{
pp[j]=i;return 1;
}
}
else if(t>0) slack=min(slack,t);
}
}
return 0;
}
void km()
{
for(int i=1;i<=n;i++)
{
while(1)
{
memset(vt1,0,sizeof(vt1));
memset(vt2,0,sizeof(vt2));
slack=0x7fffffff;
if(dfs(i)) break;
for(int j=1;j<=n;j++) if(vt1[j]!=0) cz[j]-=slack;
for(int j=1;j<=n;j++) if(vt2[j]!=0) rw[j]+=slack;
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
{
scanf("%d",&tt[i][j]);
tt[i][j]*=-1; //求最小
}
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cz[i] = max(cz[i],tt[i][j]);
km();
for(int i=1;i<=n;i++) mt+=tt[pp[i]][i];
cout<<-mt<<endl;
return 0;
}