グリッドと連結でない頂点は、最も大きい連結成分との間に辺を作る。
class AddElectricalWires { public: int maxNewWires(vector <string> G, vector <int> C) { const int N = G.size(); bool g[N][N]; bool h[N][N]; for (int i = 0; i < (int)N; ++i) { g[i][i] = h[i][i] = true; for (int j = 0; j < (int)N; ++j) { g[i][j] = (G[j][i] == '1'); h[i][j] = g[i][j]; } } for (int k = 0; k < (int)N; ++k) { for (int i = 0; i < (int)N; ++i) { for (int j = 0; j < (int)N; ++j) { g[i][j] = g[i][j] || (g[i][k] && g[k][j]); } } } int color[N]; fill(color, color + N, -1); for (int i = 0; i < (int)C.size(); ++i) { int n = C[i]; color[n] = n; for (int j = 0; j < (int)N; ++j) { int m = j; if (g[n][m]) color[m] = color[n]; } } int mx = 0; int c = color[C.front()]; for (int i = 0; i < (int)C.size(); ++i) { int tmp = count(color, color + N, C[i]); if (tmp > mx) { c = C[i]; mx = tmp; } } int ret = 0; for (int i = 0; i < (int)N; ++i) { if (color[i] == -1) { ++ret; color[i] = c; h[i][c] = h[c][i] = true; } } for (int i = 0; i < (int)N; ++i) { for (int j = i + 1; j < (int)N; ++j) { if (!h[i][j] && color[i] == color[j]) ++ret; } } return ret; } };