顶点下标1到n,边数为m,对于最大权,直接跑就可以.
如果是最小权,把边权取反,在给跑出来的答案取反即可。
val(u,v)*=-1;
ans=-KM();
由于采用的是bfs添加增广路,因此复杂度在O(n3),基本上不会被卡(好用,/st
#define inf 0x3f3f3f3f3f3f3f3f
#define ll long long
const int N = 310;
node a[N];
ll n, m, val[N][N], matched[N];
ll slack[N], pre[N], ex[N], ey[N]; //ex,ey顶标
bool visx[N], visy[N];
void bfs(ll u)
{
ll x, y = 0, yy = 0, delta;
memset(pre, 0, sizeof(pre));
for (ll i = 1; i <= n; i++)
slack[i] = inf;
matched[y] = u;
while (1)
{
x = matched[y];
delta = inf;
visy[y] = 1;
for (ll i = 1; i <= n; i++)
{
if (visy[i])
continue;
if (slack[i] > ex[x] + ey[i] - val[x][i])
{
slack[i] = ex[x] + ey[i] - val[x][i];
pre[i] = y;
}
if (slack[i] < delta)
{
delta = slack[i];
yy = i;
}
}
for (ll i = 0; i <= n; i++)
{
if (visy[i])
ex[matched[i]] -= delta, ey[i] += delta;
else
slack[i] -= delta;
}
y = yy;
if (matched[y] == -1)
break;
}
while (y)
{
matched[y] = matched[pre[y]];
y = pre[y];
}
}
ll KM()
{
memset(matched, -1, sizeof(matched));
memset(ex, 0, sizeof(ex));
memset(ey, 0, sizeof(ey));
for (ll i = 1; i <= n; i++)
{
memset(visy, 0, sizeof(visy));
bfs(i);
}
ll res = 0;
for (ll i = 1; i <= n; i++)
if (matched[i] != -1)
res += val[matched[i]][i];
return res;
}
void solve()
{
ll n, m;
cin >> n >> m; // n个点,条边,边权为val[u][v]=w,顶点下标1到n
for (int i = 1; i <= m; i++)
{
int u, v, w;
cin >> u >> v >> w;
val[u][v] = w;
}
ll ans = KM();
cout << ans << endl;
}
int main()
{
solve();
return 0;
}