CodeForces - Hello 2018 B(树的遍历). C(贪心)
B. Christmas Spruce
Consider a rooted tree. A rooted tree has one special vertex called the root. All edges are directed from the root. Vertex u is called a child of vertex v and vertex v is called a parent of vertex u if there exists a directed edge from v to u. A vertex is called a leaf if it doesn't have children and has a parent.
Let's call a rooted tree a spruce if its every non-leaf vertex has at least 3 leaf children. You are given a rooted tree, check whether it's a spruce.
The definition of a rooted tree can be found here.
The first line contains one integer n — the number of vertices in the tree (3 ≤ n ≤ 1 000). Each of the next n - 1 lines contains one integer pi (1 ≤ i ≤ n - 1) — the index of the parent of the i + 1-th vertex (1 ≤ pi ≤ i).
Vertex 1 is the root. It's guaranteed that the root has at least 2 children.
Print "Yes" if the tree is a spruce and "No" otherwise.
4 1 1 1
Yes
7 1 1 1 2 2 2
No
8 1 1 1 1 3 3 3
Yes
The first example:
The second example:
It is not a spruce, because the non-leaf vertex 1 has only 2 leaf children.
The third example:
题目大意:
给出树节点个数和每个节点的根,求这棵树是不是一颗云杉(每一个非叶子节点满足至少有三个叶子节点)。(没看到“至少”WA了一次)
思路:
构造这棵树然后进行宽搜遍历每一个节点看是否满足云杉条件。
代码:
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 1050;
vector<int >v[maxn];
queue<int> q;
int n;
int bfs()
{
int tag = 1;
q.push(1);
if(v[1].size() < 3) tag = 0;
while(q.size() && tag)
{
int t = q.front();
q.pop();
int cnt = 0;
for(int i = 0; i < v[t].size(); i++)
{
if(v[v[t][i]].size() == 0)
{
cnt++;
}
else if(v[v[t][i]].size() < 3)
{
tag = 0;
break;
}
else q.push(v[t][i]);
}
if(cnt < 3 && v[t].size() != 0) tag = 0;
}
return tag;
}
int main()
{
cin >> n;
for(int i = 2; i <= n; i++)
{
int t;
cin >> t;
v[t].push_back(i);
}
int flag = bfs();
if(flag) cout << "Yes" << endl;
else cout << "No" << endl;
return 0;
}
题目大意:
给出柠檬水的种类数和节日需要的数量及各种类的价格。已知第i种柠檬水为2^(i-1) L,求最小花费。
思路:
因为相邻柠檬水重量有两倍关系,a[i]的最优解为min(a[i], a[i-1]*2),同时如果a[i+1] < a[i], a[i] = a[i+1];遍历一次保证每一个二进制位最优,然后进行二进制枚举。如果进制位为1,加上当前位,如果二进制位为0,则要比较当前花费和a[i+1]位花费哪个更小。
代码:
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll a[32];
ll n, m, ans;
int main() {
cin >> n >> m;
for(int i = 0; i < n; i++) cin >> a[i];
for(int i = 1; i < n; i++) {
a[i] = min(a[i], a[i-1] * 2);
a[i-1] = min(a[i], a[i-1]);
}
for(int i = n; i < 31; i++) a[i] = 2 * a[i-1];
for(int i = 0; i < 30; i++) {
if(m & (1 << i)) ans += a[i];
ans = min(ans, a[i+1]);
}
cout << ans << endl;
return 0;
}
上一篇: mysql执行计划介绍_MySQL