點擊打開鏈接
思路:樹上dp,每個點的權值為d[i]+G[i].size(),然后選擇最小的刪除就好
代碼:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int maxn = 2000000+10;vector<int> G[maxn];int n,m,d[maxn],ans;bool cmp(int x,int y){ return d[x]<d[y];}void dfs(int u){ for(int i=0; i<G[u].size(); i++) dfs(G[u][i]); d[u] += G[u].size(); sort(G[u].begin(),G[u].end(),cmp); // 貪心 從重量小的開始拿 for(int i=0; i<G[u].size(); i++){ int v = G[u][i]; if(d[u]+d[v]-1<=m){ d[u] = d[u]+d[v]-1; ans++; } else break; }}int main(){ cin>>n>>m; for(int i=0; i<n; i++) scanf("%d",&d[i]); for(int i=0; i<n; i++){ int num; scanf("%d",&num); for(int j=0; j<num; j++){ int x; scanf("%d",&x); G[i].push_back(x); } } ans = 0; dfs(0); cout << ans << endl;}
新聞熱點
疑難解答