300 :
2部マッチングして正当性を確かめるまでは思い浮かんだけど
log2 で分類しきれるという所に最後まで気がつかなかった。
もっとシンプルな方法で解いてる人がいるけど、あれは何をやっているのか・・・。
450 :
読んだだけ。
1000 :
開いてない。
300
const int V = 50 * 2 + 2 + 10; struct E { int src, dst; E(int s, int d) : src(s), dst(d) {} }; vector<E> g[V]; bool vis[V]; int path[V]; int cap[V][V]; bool rec(int node, int snk, int size) { if (node == snk) return true; vis[node] = true; each (e, g[node]) { if (cap[e->src][e->dst] <= 0 || vis[e->dst]) continue; path[e->dst] = e->src; if (rec(e->dst, snk, size)) return true; } return false; } int flow(int src, int snk, int size) { int res = 0; fill(vis, vis + size, false); while (rec(src, snk, size)) { fill(vis, vis + size, false); for (int i = snk; i != src; i = path[i]) { --cap[path[i]][i]; ++cap[i][path[i]]; } ++res; } return res; } class SwitchesAndLamps { public: int theMin(vector <string> S, vector <string> L) { const int size = S[0].size(); const int src = size * 2; const int snk = size * 2 + 1; fill(g, g + V, vector<E>()); fill(&cap[0][0], &cap[V - 1][V], 0); for (int s = 0; s < (int)size; ++s) { for (int l = 0; l < (int)size; ++l) { bool flg = true; for (int i = 0; i < (int)S.size(); ++i) { flg = flg && S[i][s] == L[i][l]; } if (flg) { g[s].push_back(E(s, l + size)); g[l + size].push_back(E(l + size, s)); cap[s][l + size] = 1; } } } for (int s = 0; s < (int)size; ++s) { cap[src][s] = 1; g[src].push_back(E(src, s)); } for (int l = 0; l < (int)size; ++l) { cap[l + size][snk] = 1; g[l + size].push_back(E(l + size, snk)); } if (size != flow(src, snk, snk + 1)) return -1; int mx = 0; for (int i = 0; i < size; ++i) { mx = max(mx, (int)g[i].size()); } return (int)ceil(log2(mx)); } };