大概是给定一棵树,任意删掉一个叶子节点到根节点路径上的结点,得到一个森林,求得到最大森林数。
示例: 7 1 2 1 3 2 4 2 5 3 6 3 7
得到如下所示的树: 删掉叶子节点4到根节点1的路径上的结点1->2->4,剩下两棵树:5和(3, 6, 7) 删除其他叶子节点最大也只能获得两棵树,所以最后结果输出2。
我的解法是首先定义post用来记录每一个节点的父节点,比如post[4] = 2。然后找到叶子节点存到vector yezi中,这里显然是(4, 5, 6, 7)。 然后循环遍历yezi,找出每一次删除一条路径能得到的森林数,取最大输出。 但是最后提交系统并没有过全部案例,代码贴在下面,希望得到有心人的答复。
#include<bits/stdc++.h> using namespace std; map<int, int> post; vector<int> mask; //这个函数作用是求出去掉叶子节点到根节点路径上节点后,每个节点的父节点 int findfather(int a) { while(mask[post[a]] != 1) { a = post[a]; } return a; } int main() { int n; cin >> n; vector<int> output(n+1, 0); //用来记录出度,用来找叶子节点 for(int i = 1; i < n; i++) { int a, b; cin >> a >> b; post[b] = a; output[a]++; } //这里是找出叶子节点,存在yezi中 vector<int> yezi; for(int i = 1; i <= n; i++) { if(output[i] == 0) { yezi.push_back(i); } } //遍历叶子节点,看删除哪个叶子使得得到的森林最大 int maxtree = 0; for(int i = 0; i < yezi.size(); i++) { int firstyezi = yezi[i]; //拿到当前叶子 int temp = firstyezi; //mask表示是否去掉,mask==1表示去掉的结点,后面不予考虑 mask = vector<int>(n+1, 0); while(temp != 1) { mask[temp] = 1; temp = post[temp]; } mask[1] = 1;//根节点不管怎么样都会去掉的 //这里集合s用来保存剩下森林的根节点 set<int> s; for(int i = 1; i <= n; i++) { if(mask[i] != 1) { s.insert(findfather(i)); } } int tree = s.size(); //得到去除当前叶节点后最大森林数目 maxtree = max(maxtree, tree); } cout << maxtree; return 0; }