您的位置:首页 > 其它

[HEOI2015]兔子与樱花

2017-05-18 22:05 218 查看
算我傻逼,看错题

对于一个节点,能选尽量选,那么选一个子节点的代价是c[v]+lson[v]

排序贪心,树型DP即可

#include <cstdio>
#include <algorithm>

using namespace std;

const int SN = 2000000 + 10;

int c[SN], n, head[SN], ans, num, x, u,tmp[SN], cnt, m, s[SN];

struct Edge {
int from,to,next;
}E[SN<<1];

void Read(int &x) {
int in = 0,f = 1;char ch = getchar();
while(ch<'0' || ch>'9') {if(ch=='-') f = -1;ch = getchar();}
while(ch>='0' && ch<='9') {in = in*10+ch-'0';ch = getchar();}
x = in*f;
}

void Add(int u,int v) {
E[++num].from = u;
E[n
9cd3
um].to = v;
E[num].next = head[u];
head[u] = num;
}

void dfs(int u,int fa) {

for(int i = head[u]; i; i = E[i].next) {
int to = E[i].to;
if(to == fa)    continue;
dfs(to,u);
}

cnt = 0;
for(int i = head[u]; i; i = E[i].next) {
tmp[++cnt] = c[E[i].to]-1; //去掉的是点权,并且儿子数会少1
//WA了几发,一开始直接把lson[]加到点权中
}

c[u] += cnt;

sort(tmp+1,tmp+cnt+1);

for(int i = 1; i <= cnt; i++) {
if(c[u] + tmp[i] <= m) {
c[u] += tmp[i];
ans++;
}
else break;
}
}

int main() {

Read(n),Read(m);

for(int i = 0; i < n; i++) {
Read(c[i]);s
= c[i];
}

for(int i = 0; i < n; i++) {
Read(x);
for(int j = 1; j <= x; j++) {
Read(u);
Add(i,u);
}
}

dfs(0,-1);

printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: