11.02T3 贪心

1能量获取3764

(power.cpp/c/pas)

【问题描述】

  封印台是一个树形的结构,魂珠放置的位置就是根节点(编号为 0)。还有 n 个其它节点(编号 1~n)上放置着封印石,编号为i的封印石需要从魂珠上获取 Ei 的能量。能量只能沿着树边从魂珠传向封印石,每条边有一个能够传递的能量上限 Wi,魂珠的能量是无穷大的。作为封印开始前的准备工作,请你求出最多能满足多少颗封印石的能量需求? 
   注意:能量可以经过一个节点,不满足它的需求而传向下一个节点。每条边仅能传递一次能量。

【输入】

  第一行一个整数n,表示除根节点之外其它节点的数量。 
  接下来 n 行,第 i+1 行有三个整数 Fi、Ei、Wi,分别表示 i 号节点的父节点、i 号节点上封印石的能量需求、连接节点 i与Fi的边最多能传递多少能量。

【输出】

  最多能满足多少颗封印石的能量需求。

【输入样例】

4

0 3 2

0 100 100

1 1 1

2 75 80

【输出样例】

2

【数据范围与约定】 
  对于100%的数据,满足1<=n<=1000,0<=Fi<=n,0<=Ei,Wi<=100。

【分析】贪心

    每次选取能量需求最小的节点,扫描它到根节点的路径上的边的容量,看能否满足,如果能满足就把它到根节点的路径上的边的容量都减去它的需求即可。

   本题如果把握不好贪心的正确性也可以写树状动规(多叉树,背包转移),但是显然编程复杂度就上升了一个层次。

 

 

 

少见的贪心,其实树上背包也挺简单的

code:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #define N 100006
 5 using namespace std;
 6 struct node{
 7     int id,w;
 8 }p[N];
 9 int fa[N],w[N],E[N];
10 bool cmp(const node&a,const node&b){
11     return a.w<b.w;
12 }
13 int main(){
14     int n;cin>>n;
15     for(int i=1;i<=n;i++){
16         cin>>fa[i]>>p[i].w>>w[i];
17         p[i].id=i;
18     }
19     sort(p+1,p+n+1,cmp);
20     int ans=0;
21     for(int i=1;i<=n;i++){
22         int min0=99999999;
23         int temp=p[i].id;
24         while(temp){
25             min0=min(min0,w[temp]);
26             temp=fa[temp];
27 //            cout<<temp<<"<-temp";
28         }
29 //        cout<<'\n';
30 //        cout<<p[i].id<<" "<<min0<<'\n';
31         if(min0>=p[i].w){
32             ans++;
33             temp=p[i].id;
34             while(temp){
35                 w[temp]-=p[i].w;
36                 temp=fa[temp];
37             }
38         }
39     }
40     cout<<ans;
41     return 0;
42 }

over

转载于:https://www.cnblogs.com/saionjisekai/p/9902138.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值