classSolution { structUF { vector<int> parent; int count; UF(int n) : parent(n), count(n) { iota(parent.begin(), parent.end(), 0); } // A utility function to find the subset of an element i intfind(int x) { return x == parent[x] ? x : parent[x] = find(parent[x]); }
// A utility function to do union of two subsets voidunite(int x, int y) { int xset = find(x); int yset = find(y); if(xset != yset) { parent[xset] = yset; --count; } } }; public: vector<int> countSubgraphsForEachDiameter(int n, vector<vector<int>>& edges){ // time: (n ^ 2 * 2 ^ n) vector<unordered_set<int>> graph(n); for (constauto& v : edges) { constint a = v[0] - 1; constint b = v[1] - 1; graph[a].insert(b); graph[b].insert(a); } vector<vector<int>> dist(n, vector<int>(n)); function<void(constint, constint, constint, constint)> dfs = [&](constint root, constint current, constint parent, constint depth) -> void { dist[root][current] = depth; for (int child : graph[current]) { if (child == parent) continue; dfs(root, child, current, depth + 1); } }; for (int i = 0; i < n; ++i) { dfs(i, i, -1, 0); } auto getnodes = [&](constint mask) -> vector<int> { vector<int> ans; for (int i = 0; i < n; ++i) { if ((mask & (1 << i)) != 0) { ans.push_back(i); } } return ans; }; auto checksubtree = [&](const vector<int>& nodes) -> bool { if (nodes.empty() || nodes.size() == 1) returnfalse; UF uf(n); for (int i = 0; i < nodes.size(); ++i) { for (int j = i + 1; j < nodes.size(); ++j) { constint a = nodes[i], b = nodes[j]; if (graph[a].find(b) != graph[a].end()) { uf.unite(a, b); } } } int root = -1; for (int a : nodes) { if (root == -1) { root = uf.find(a); } else { if (root != uf.find(a)) returnfalse; } } returntrue; }; auto distance = [&](const vector<int>& nodes) -> int { int ans = 0; for (int i = 0; i < nodes.size(); ++i) { for (int j = i + 1; j < nodes.size(); ++j) { constint a = nodes[i], b = nodes[j]; ans = max(ans, dist[a][b]); } } return ans; }; // d = 1...n-1 vector<int> ans(n - 1, 0); constint upper = (1 << n); for (int mask = 0; mask < upper; ++mask) { auto nodes = getnodes(mask); if (!checksubtree(nodes)) continue; ++ans[distance(nodes) - 1]; } return ans; } };