题解:CF1264E Beautiful League
Priestess_SLG · · 题解
为啥有黑来着。
有经典结论:竞赛图三元环数量为
后面部分十分套路,考虑费用流建模。如果
则此时若
记第
:::success[Code]
namespace lowspeed_song {
vector<int> adj[N];
int deg[N], win[N], mt[55][55];
char res[55][55];
namespace MCMF {
int S, T, hhh[N], e[N], f[N], ne[N], w[N], idxx, q[N], d[N], pre[N], incf[N], st[N];
inline void ae(int a, int b, int c, int d) {
e[idxx] = b, w[idxx] = d, f[idxx] = c, ne[idxx] = hhh[a], hhh[a] = idxx++;
e[idxx] = a, w[idxx] = -d, f[idxx] = 0, ne[idxx] = hhh[b], hhh[b] = idxx++;
}
inline int spfa() {
int hh = 0, tt = 1;
memset(d, 0x3f, sizeof d);
memset(incf, 0, sizeof incf);
q[0] = S, d[S] = 0, incf[S] = inf;
while (hh != tt) {
int t = q[hh++];
if (hh == N) hh = 0;
st[t] = 0;
for (int i = hhh[t]; ~i; i = ne[i]) {
int v = e[i];
if (f[i] && d[v] > d[t] + w[i]) {
d[v] = d[t] + w[i];
pre[v] = i, incf[v] = min(incf[t], f[i]);
if (!st[v]) {
q[tt++] = v;
if (tt == N) tt = 0;
st[v] = 1;
}
}
}
}
return incf[T] > 0;
}
inline void ek(int &F, int &C) {
F = C = 0;
while (spfa()) {
int tt = incf[T];
F += tt, C += tt * d[T];
for (int i = T; i != S; i = e[pre[i] ^ 1]) f[pre[i]] -= tt, f[pre[i] ^ 1] += tt;
}
}
}
inline void init() {
}
inline void sol([[maybe_unused]]int __testcase_id) {
int n, m; cin >> n >> m;
vector<pair<int, int>> unk;
memset(MCMF::hhh, -1, sizeof MCMF::hhh);
for (int i = 0; i < n; ++i) res[i][i] = '0';
while (m--) {
int u, v; cin >> u >> v; --u, --v;
adj[u].emplace_back(v), adj[v].emplace_back(u);
res[u][v] = '1', res[v][u] = '0', mt[u][v] = mt[v][u] = 1, ++win[u];
} for (int i = 0; i < n; ++i) for (int j = i + 1; j < n; ++j) if (!mt[i][j])
++deg[i], ++deg[j], unk.emplace_back(i, j);
MCMF::S = N - 1, MCMF::T = N - 2;
vector<tuple<int, int, int>> match;
for (int i = 0; i < unk.size(); ++i) {
auto [u, v] = unk[i];
MCMF::ae(MCMF::S, n + i + 1, 1, 0);
MCMF::ae(n + i + 1, u, 1, 0);
MCMF::ae(n + i + 1, v, 1, 0);
match.emplace_back(u, v, MCMF::idxx - 4);
}
for (int i = 0; i < n; ++i)
for (int j = 0; j < deg[i]; ++j) MCMF::ae(i, MCMF::T, 1, win[i] + j);
int F, C; MCMF::ek(F, C);
for (auto &[u, v, eu] : match) {
if (!MCMF::f[eu]) res[u][v] = '1', res[v][u] = '0';
else res[v][u] = '1', res[u][v] = '0';
} for (int i = 0; i < n; ++i, cout << '\n')
for (int j = 0; j < n; ++j) cout << res[i][j];
}
} // namespace lowspeed_song
:::