给你 n 个城市,编号为从 1 到 n 。同时给你一个大小为 n-1 的数组 edges ,其中 edges[i] = [ui, vi]
表示城市 ui 和 vi 之间有一条双向边。
题目保证任意城市之间只有唯一的一条路径。换句话说,所有城市形成了一棵 树 。
一棵 子树 是城市的一个子集,且子集中任意城市之间可以通过子集中的其他城市和边到达。 两个子树被认为不一样的条件是至少有一个城市在其中一棵子树中存在,但在另一棵子树中不存在。
对于 d 从 1 到 n-1 ,请你找到城市间 最大距离 恰好为 d 的所有子树数目。
请你返回一个大小为 n-1 的数组,其中第 d 个元素(下标从 1 开始)是城市间 最大距离 恰好等于 d 的子树数目。
请注意,两个城市间距离定义为它们之间需要经过的边的数目。
示例 1:
输入:n = 4, edges = [[1,2],[2,3],[2,4]]
输出:[3,4,0]
解释:
子树 {1,2}, {2,3} 和 {2,4} 最大距离都是 1 。
子树 {1,2,3}, {1,2,4}, {2,3,4} 和 {1,2,3,4} 最大距离都为 2 。
不存在城市间最大距离为 3 的子树。
示例 2:
输入:n = 2, edges = [[1,2]]
输出:[1]
示例 3:
输入:n = 3, edges = [[1,2],[2,3]]
输出:[2,1]
提示:
2 <= n <= 15
edges.length == n-1
edges[i].length == 2
1 <= ui, vi <= n
题目保证 (ui, vi) 所表示的边互不相同。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/count-subtrees-with-max-distance-between-cities 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
类似题目:LeetCode 1245. 树的直径(图的最大直径结论)
class Solution {
vector<int> ans;
vector<vector<int>> g;//图
vector<int> sub;//子节点集
int N;
public:
vector<int> countSubgraphsForEachDiameter(int n, vector<vector<int>>& edges) {
N = n;
sub = vector<int> (n, 0);
ans = vector<int> (n-1, 0);
g.resize(n);
for(auto& e : edges)
{
g[e[0]-1].push_back(e[1]-1);
g[e[1]-1].push_back(e[0]-1);
}
dfs(0);
return ans;
}
void dfs(int i)
{
if(i == N)
{
int d = calculateD();
if(d != -1)
ans[d-1]++;
return;
}
dfs(i+1);//当前点不选
sub[i] = 1;//标记节点选中了
dfs(i+1);//当前点选
sub[i] = 0;//回溯
}
int calculateD()//判断联通,以及最大直径
{
int start = -1;
for(int i = 0; i < N && start == -1; ++i)
if(sub[i] == 1)
start = i;
int last = bfs(start, true);//以任意一点开始bfs
if(last == -1)//图不连通,返回
return -1;
return bfs(last, false);//以last点开始bfs求最大直径
}
int bfs(int id, bool option)
{
int count = 0, total = accumulate(sub.begin(),sub.end(),0);
if(total <= 1)
return -1;// 少于2个点,不满足题意
int last, size, step = 0;
vector<int> unvis(sub);
queue<int> q;
q.push(id);
unvis[id] = 0;
while(!q.empty())
{
size = q.size();
while(size--)
{
last = id = q.front();
q.pop();
count++;
for(int nt : g[id])
{
if(unvis[nt])
{
unvis[nt] = 0;
q.push(nt);
}
}
}
step++;
}
if(option == true)
{
if(count != total)
return -1;//不连通
return last;//最后一个点
}
else
{
return step-1;
}
}
};
1140 ms 399.6 MB