leetcode LCP 26. 导航装置
瘤瘤问我的。
给定一棵二叉树,找出其中Q个关键点,使得这棵树上不存在某两个点,到所有的关键点距离都相同。无边权。输出最小的Q。
一开始是想的直径,后来发现从直径上某个点伸出去两条分叉就不行。然后接着思考不行的情况,发现:
所有的关键点连接起来,会形成若干条路径。
每条路径上的点都能被区分。
如果某个路径上的点开始,出现了不在路径上的分叉,就不行。
然后借此写个树形的贪心(?)就可以了。
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 struct Edge { 12 int nex, v; 13 }edge[100010]; int tp = 0; 14 int ans = 0, e[50010], deg[50010], n = 0; 15 16 inline void add(int x, int y) { 17 deg[x]++; 18 edge[++tp].v = y; 19 edge[tp].nex = e[x]; 20 e[x] = tp; 21 return; 22 } 23 24 int dfs(int x, int fa) { 25 int son = deg[x] - 1, t = 0, no = 0; 26 for(int i = e[x]; i; i = edge[i].nex) { 27 int y = edge[i].v; 28 if(y == fa) continue; 29 int temp = dfs(y, x); 30 t |= temp; 31 if(!temp) { 32 no++; 33 } 34 } 35 if(!son) { 36 return 0; 37 } 38 if(son == 1) { 39 return t; 40 } 41 else if(no > 1) { 42 ans += no - 1; 43 return 1; 44 } 45 else { 46 return 1; 47 } 48 } 49 50 void dfs1(TreeNode *x) { 51 n = std::max(n, x->val); 52 if((x->left) != nullptr) { 53 dfs1(x->left); 54 add(x->val, x->left->val); 55 add(x->left->val, x->val); 56 } 57 if((x->right) != nullptr) { 58 dfs1(x->right); 59 add(x->val, x->right->val); 60 add(x->right->val, x->val); 61 } 62 } 63 64 public: 65 int navigation(TreeNode* root) { 66 memset(deg, 0, sizeof(deg)); 67 memset(e, 0, sizeof(e)); 68 dfs1(root); 69 int r = 0; 70 for(int i = 1; i <= n; i++) { 71 if(deg[i] == 3) { 72 r = i; 73 break; 74 } 75 } 76 if(r == 0) { 77 return 1; 78 } 79 dfs(r, 0); 80 return ans; 81 } 82 };