本KM代码可以通过2019ICPC南京的J题,是真正的n^3,可放心使用。
2019 Nanjing Regional 被卡了KM之后,又在训练的时候做到了一个KM的题…
于是就搞了一份bfs 的 KM…只测了这一个题,还不知道复杂度具体是多少。
这个题是算乘法的最大值,转化成log就直接最大权匹配了…
n是100,这题应该没卡费用流。
(我自闭了,我搞了份dfs的KM发现CF上只跑了31MS,而本代码跑了46MS…)
不管了,先放上代码再说…
(我继续研究复杂度去了…)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define FOR(i, x, y) for (LL i = (x), _##i = (y); i < _##i; ++i)
#define FORD(i, x, y) for (LL i = (x), _##i = (y); i > _##i; --i)
#ifdef zerol
#define dbg(args...) do { cout << "\033[32;1m" << #args<< " -> "; err(args); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template<typename T, typename... Args>
void err(T a, Args... args) { cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
// -----------------------------------------------------------------------------
const int maxn = 110;
const double INF = 1e18;
int n,nl,nr,m;
double a[maxn][maxn];
double slk[maxn],sl[maxn],sr[maxn];
int pre[maxn],match[maxn];
bool vis[maxn];
void bfs(int s)
{
for(int i=0;i<maxn;i++)
{
slk[i] = INF;
vis[i] = 0;
pre[i] = 0;
}
int u,nt,nw;
double d;
match[u=0] = s;
do
{
nw = match[u];
d = slk[0];
vis[u] = true;
for(int v=1;v<=n;v++)
{
if(!vis[v])
{
if(sl[nw]+sr[v]-a[nw][v]<slk[v])
{
slk[v] = sl[nw]+sr[v]-a[nw][v];
pre[v] = u;
}
if(d>slk[v])
{
d = slk[v];
nt = v;
}
}
}
for(int i=0;i<=n;i++)
{
if(vis[i])
{
sl[match[i]] -= d;
sr[i] += d;
}
else slk[i] -= d;
}
u = nt;
}while(match[u]);
while(u)
{
match[u] = match[pre[u]];
u = pre[u];
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
double x;
scanf("%lf",&x);
a[i][j] = max(a[i][j],log2(x));
sl[i] = max(sl[i],a[i][j]);
}
}
for(int i=1;i<=n;i++) bfs(i);
for(int i=1;i<=n;i++) printf("%d%c",match[i]," \n"[i==n]);
return 0;
}