奔小康赚大钱
题解
抄了一下午代码,抄错了一个字母。
//Twenty
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define INF 0xfffffff
const int maxn=305;
typedef long long LL;
using namespace std;
int n,cx[maxn],cy[maxn],x[maxn],y[maxn],pr[maxn],slack[maxn];
int a[maxn][maxn];
int find(int u) {
x[u]=1;
for(int i=1;i<=n;i++) {
if(!y[i]){
if(cx[u]+cy[i]==a[u][i]) {
y[i]=1;
if(pr[i]==-1||find(pr[i])) {
pr[i]=u;
return 1;
}
}
else slack[i]=min(slack[i],-a[u][i]+cx[u]+cy[i]);
}
}
return 0;
}
void work() {
memset(pr,-1,sizeof(pr));
memset(cy,0,sizeof(cy));
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) slack[j]=INF;
for(;;) {
memset(x,0,sizeof(x));
memset(y,0,sizeof(y));
if(find(i)) break;
int d=INF;
for(int j=1;j<=n;j++)
if(!y[j]&&d>slack[j])
d=slack[j];
if(d==INF) return;
for(int j=1;j<=n;j++) {
if(x[j]) cx[j]-=d;
if(y[j]) cy[j]+=d;
else slack[j]-=d;
}
}
}
int ans=0;
for(int i=1;i<=n;i++)
ans+=a[pr[i]][i];
printf("%d\n",ans);
}
void init() {
while(~scanf("%d",&n)) {
for(int i=1;i<=n;i++) {
cx[i]=-INF;
for(int j=1;j<=n;j++) {
scanf("%d",&a[i][j]);
cx[i]=max(cx[i],a[i][j]);
}
}
work();
}
}
int main() {
init();
return 0;
}