あるクライアントとあるサーバを直に結ぶケーブルにゲートを設置するかどうかは、
トポロジカル順序でそのクライアントとサーバの間にあるコンピュータのかに、
そのクライアントから到達可能で、そのサーバへ到達可能なコンピュータが1つでもあるかどうかによる。
class NetworkSecurity { public: int secureNetwork(vector <string> C, vector <string> S) { const int node = C.size() + S[0].size(); bool g[node][node]; fill(&g[0][0], &g[node - 1][node], false); for (int i = 0; i < (int)C.size(); ++i) { for (int j = 0; j < (int)C.size(); ++j) { g[i][j] = C[i][j] == 'Y'; } } for (int i = 0; i < (int)C.size(); ++i) { for (int j = 0; j < (int)S[0].size(); ++j) { g[i][j + C.size()] = S[i][j] == 'Y'; } } bool h[node][node]; copy(&g[0][0], &g[node - 1][node], &h[0][0]); for (int k = 0; k < (int)node; ++k) { for (int i = 0; i < (int)node; ++i) { for (int j = 0; j < (int)node; ++j) { h[i][j] = h[i][j] || (h[i][k] && h[k][j]); } } } vector<int> ord; vector<int> v; int deg[node]; fill(deg, deg + node, 0); for (int i = 0; i < (int)node; ++i) { for (int j = 0; j < (int)node; ++j) { if (g[i][j]) ++deg[j]; } } for (int i = 0; i < (int)node; ++i) { if (deg[i] == 0) v.push_back(i); } while (v.size()) { int n = v.back(); v.pop_back(); ord.push_back(n); for (int m = 0; m < node; ++m) { if (g[n][m]) { g[n][m] = false; if (--deg[m] == 0) v.push_back(m); } } } int o[node]; for (int i = 0; i < (int)node; ++i) { o[ord[i]] = i; } int ret = 0; for (int c = 0; c < (int)C.size(); ++c) { for (int s = C.size(); s < (int)node; ++s) { if (h[c][s] && o[c] < o[s]) { bool flg = true; for (int i = o[c] + 1; i < o[s]; ++i) { if (h[c][ord[i]] && h[ord[i]][s] && h[ord[i]][s]) flg = false; } ret += flg; } } } return ret; } };