KM模板(带权的二分匹配)
int vx[N],vy[N],lx[N],ly[N],link[N],mat[N][N];
int n;
int dfs(int t)
{
int i;
vx[t]=1;
for(i=1; i<=n; i++)
{
if(vy[i]==0&&lx[t]+ly[i]==mat[t][i])
{
vy[i]=1;
if(link[i]==-1||dfs(link[i]))
{
link[i]=t;
return 1;
}
}
}
return 0;
}
int KM()
{
int i,j,t,k;
memset(lx,0,sizeof(lx));
memset(ly,0,sizeof(ly));
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
lx[i]=max(lx[i],mat[i][j]);
for(i=1; i<=n; i++)
{
while(1)
{
memset(vx,0,sizeof(vx));
memset(vy,0,sizeof(vy));
if(dfs(i))
break;
else
{
t=inf;
for(j=1; j<=n; j++)
if(vx[j])
for(k=1; k<=n; k++)
if(vy[k]==0&&lx[j]+ly[k]-mat[j][k]<t)
t=lx[j]+ly[k]-mat[j][k];
for(j=1; j<=n; j++)
{
if(vx[j])
lx[j]-=t;
if(vy[j])
ly[j]+=t;
}
}
}
}
int sum=0;
for(int i=1; i<=n; i++)
sum+=mat[link[i]][i];
return sum;
}