一切尽在代码中
#include<bits/stdc++.h>
using namespace std;
const int maxn = 55;
const int inf = 1 << 30;
const int64_t mod = 1e9 + 7;
int w[maxn][maxn];
int lx[maxn], ly[maxn];
int linky[maxn], linkx[maxn];
bool visx[maxn], visy[maxn];
int slack[maxn];
int n, m;
bool Find(int x)//匈牙利算法求是否有合法匹配点
{
visx[x] = true;
for(int y = 0; y < m; y++)
{
if(visy[y]) continue;
int t = lx[x] + ly[y] - w[x][y];
if(!t)
{
visy[y] = true;
if(linky[y] == -1 || Find(linky[y]))
{
linky[y] = x;
linkx[x] = y;
return true;
}
}
else
slack[y] = min(slack[y], t);
}
return false;
}
int KM()
{
memset(linky, -1, sizeof(linky));
memset(ly, 0, sizeof(ly));//初始时所有都在权值都在lx
for(int v = 0; v < n; v++)//逐步增大二分子图
{
for(int j = 0; j < m; j++) slack[j] = inf;
while(true)
{
memset(visx, 0, sizeof(visx));
memset(visy, 0, sizeof(visy));
if(Find(v))
break;
int d = inf;
for(int i = 0; i < m; i++)
{
if(!visy[i])
{
d = min(d, slack[i]); //算法贪心性质这里体现
}
}
if(d == inf) return -1;
for(int i = 0; i < n; i++)
{
if(visx[i])
{
lx[i] -= d;
}
}
for(int i = 0; i < m; i++)
{
if(visy[i])
ly[i] += d;
else
slack[i] -= d;//在这个while循环中是叠加的,所以后面的slack要减去当前d
}
}
}
int res = 0;
for(int i = 0; i < m; i++)
{
//cout << linkx[i] << " " << linky[i] << endl;
if(linky[i] != -1) res += w[linky[i]][i];
}
return res;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
int P[maxn][maxn], Q[maxn][maxn];
cin >> n;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
cin >> P[i][j];
}
}
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
cin >> Q[i][j];
}
}
m = n;
for(int i = 0; i < n; i++)
{
lx[i] = -inf;
for(int j = 0; j < m; j++)
{
lx[i] = max(lx[i], w[i][j] = P[i][j] * Q[j][i]);//初始时lx[i]为i连的最大边权
}
//cout << lx[i] << endl;
}
cout << KM() << endl;
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int maxn = 305;
const int inf = 1 << 30;
const int64_t mod = 1e9 + 7;
int w[maxn][maxn];
int lx[maxn], ly[maxn];
int linky[maxn], linkx[maxn];
bool visx[maxn], visy[maxn];
int slack[maxn];
int n, m;
bool Find(int x)//匈牙利算法求是否有合法匹配点
{
visx[x] = true;
for(int y = 0; y < m; y++)
{
if(visy[y]) continue;
int t = lx[x] + ly[y] - w[x][y];
if(!t)
{
visy[y] = true;
if(linky[y] == -1 || Find(linky[y]))
{
linky[y] = x;
linkx[x] = y;
return true;
}
}
else
slack[y] = min(slack[y], t);
}
return false;
}
int KM()
{
memset(linky, -1, sizeof(linky));
memset(ly, 0, sizeof(ly));//初始时所有都在权值都在lx
for(int v = 0; v < n; v++)//逐步增大二分子图
{
for(int j = 0; j < m; j++) slack[j] = inf;
while(true)
{
memset(visx, 0, sizeof(visx));
memset(visy, 0, sizeof(visy));
if(Find(v))
break;
int d = inf;
for(int i = 0; i < m; i++)
{
if(!visy[i])
{
d = min(d, slack[i]); //算法贪心性质这里体现
}
}
if(d == inf) return -1;
for(int i = 0; i < n; i++)
{
if(visx[i])
{
lx[i] -= d;
}
}
for(int i = 0; i < m; i++)
{
if(visy[i])
ly[i] += d;
else
slack[i] -= d;//在这个while循环中是叠加的,所以后面的slack要减去当前d
}
}
}
int res = 0;
for(int i = 0; i < m; i++)
{
//cout << linkx[i] << " " << linky[i] << endl;
if(linky[i] != -1) res += w[linky[i]][i];
}
return res;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
while(cin >> n)
{
m = n;
for(int i = 0; i < n; i++)
{
lx[i] = -inf;
for(int j = 0; j < m; j++)
{
cin >> w[i][j];
lx[i] = max(lx[i], w[i][j]);
}
}
cout << KM() << endl;
}
return 0;
}