1617. Count Subtrees With Max Distance Between Cities

问题:

给定n个节点,以及节点直接的连线数组edges

已知,这些节点代表城市,这些城市构成一棵树,

即任意两节点都有唯一路径。

求,这些城市中的子树中,各个最大路径的子树个数。

Example 1:
Input: n = 4, edges = [[1,2],[2,3],[2,4]]
Output: [3,4,0]
Explanation:
The subtrees with subsets {1,2}, {2,3} and {2,4} have a max distance of 1.
The subtrees with subsets {1,2,3}, {1,2,4}, {2,3,4} and {1,2,3,4} have a max distance of 2.
No subtree has two nodes where the max distance between them is 3.

Example 2:
Input: n = 2, edges = [[1,2]]
Output: [1]

Example 3:
Input: n = 3, edges = [[1,2],[2,3]]
Output: [2,1]
 
Constraints:
2 <= n <= 15
edges.length == n-1
edges[i].length == 2
1 <= ui, vi <= n
All pairs (ui, vi) are distinct.

Example 1:

 

⚠️ 注意:Example 1中所有的子树(至少有两个城市)有:

[1,2] [2,3] [2,4]

[1,2,3] [1,2,4]

[1,2,3,4]

而:

[1,3] [1,4] [1,3,4]没有全联通,因此不算子树。

 

解法:bitmask->Combination 组合。

例如:state:1101

代表组合:[1,2,4]

代码做法:

//遍历n个元素的组合: 
       for(int state=0; state<(1<<n); state++) {
            //bitmask to get combination
            ...
        }
//翻译对应组合:
        for(int i=0; i<n; i++) {//对应元素 i: 0,1,2...n-1
            //this node i doesn't exist.
            if(((state>>i)&1) == 0) continue;
            //this node i exists.
            if(((state>>i)&1) == 1) {
                 ...
            }
        }

 

本题解法:

根据给出的【节点直接的连线数组edges】

1. 创建任意两节点的距离数组distance:

  <1> 直接相连距离: 距离=1

distance[i][j] == distance[j][i]

由于节点无向,因此交换也保存。

  <2> 间接相连距离构建:距离=

distance[i][j] = distance[i][k] + distance[k][j]

 

2. 遍历所有组合:

找到合法子树(node数==edge数+1)

求最大距离。

 

代码参考:

 1 class Solution {
 2 public:
 3     vector<vector<int>> distance;
 4     int getmaxdis(int state, int n) {//this state comb:0~n
 5         //state: 01101
 6         //city:  01234->{1,2,4}
 7         int maxdis = 0;
 8         int city_n = 0, edge_n = 0;
 9         for(int i=0; i<n; i++) {
10             if(((state>>i)&1) == 0) continue;//this city i doesn't exist.
11             city_n++;
12             for(int j=i+1; j<n; j++) {
13                 if(((state>>j)&1) == 0) continue;//this city j doesn't exist.
14                 if(distance[i][j]==1)edge_n++;// 2 cities -> 1 edge
15                 maxdis = max(maxdis, distance[i][j]);
16             }
17         }
18         if(city_n!=edge_n+1) return 0;// invalid set which can't be a tree (like ex1: {1,3,4})
19         return maxdis;
20     }
21     vector<int> countSubgraphsForEachDiameter(int n, vector<vector<int>>& edges) {
22         vector<int>res(n-1, 0);
23         int INF = n;//the max value of the set: n
24         distance.resize(n, vector<int>(n, INF));
25         for(vector<int>& edge:edges) {
26             distance[edge[0]-1][edge[1]-1] = 1;
27             distance[edge[1]-1][edge[0]-1] = 1;
28         }
29         //get all distance
30         for(int k=0; k<n; k++) {//过渡节点
31             for(int i=0; i<n; i++) {
32                 for(int j=0; j<n; j++) {
33                     distance[i][j] = min(distance[i][j], distance[i][k]+distance[k][j]);
34                 }
35             }
36         }
37         
38         //for each set, get res
39         for(int state=0; state<(1<<n); state++) {//bitmask to get combination
40             int d = getmaxdis(state, n);
41             if(d>0) res[d-1]++;
42         }
43         
44         return res;
45     }
46 };

 

posted @ 2021-02-13 13:30  habibah_chang  阅读(133)  评论(0编辑  收藏  举报