关于刚才 abc 的 F
  • 板块学术版
  • 楼主Phartial静月千阴
  • 当前回复3
  • 已保存回复3
  • 发布时间2022/7/9 21:50
  • 上次更新2023/10/27 21:18:25
查看原帖
关于刚才 abc 的 F
376161
Phartial静月千阴楼主2022/7/9 21:50

rt,思路是 f[i][0/1]f[i][0/1] 表示以 ii 为根的子树中父亲边选或不选,能够得到的最大收益

然后对于每棵子树求出 f[j][0]f[j][0]f[j][1]f[j][1],如果 f[j][0]f[j][1]f[j][0]\ge f[j][1]f[j][0]f[j][0] 为正数那么 f[j][0]f[j][0] 肯定比 f[j][1]f[j][1] 要优,直接选上;否则如果 f[j][1]>0f[j][1] >0 就把 f[j][1]f[j][1] 丢到一个列表里,最后选出前 d[x]d[x] 大的选上。

然而在第二个样例错了,求助是思路假了还是代码有问题

#include <atcoder/all>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <deque>
#include <functional>
#include <iomanip>
#include <map>
#include <set>
#ifndef ONLINE_JUDGE
#define debug(...) fprintf(stderr, __VA_ARGS__)
#else
#define debug(...)
#endif

using namespace std;
using namespace atcoder;
using LL = long long;
using Pii = pair<int, int>;
using Pll = pair<LL, LL>;
using mL = modint998244353;

const int kN = 3e5 + 1;

int n, d[kN];
LL f[kN][2], a[kN];
vector<Pii> e[kN];

LL D(int x, int p, int l) {
  if (~f[x][l]) {
    return f[x][l];
  }
  d[x] -= l, f[x][l] = 0;
  int c = 0;
  for (Pii i : e[x]) {
    if (i.first != p) {
      D(i.first, x, 0);
      if (d[i.first]) {
        D(i.first, x, 1), i.second > 0 && (f[i.first][1] += i.second);
        if (f[i.first][0] >= f[i.first][1] && f[i.first][0] > 0) {
          f[x][l] += f[i.first][0];
        } else if (f[i.first][1] > f[i.first][0] && f[i.first][1] > 0) {
          a[++c] = f[i.first][1];
        }
        i.second > 0 && (f[i.first][1] -= i.second);
      } else {
        if (f[i.first][0] >= 0) {
          f[x][l] += f[i.first][0];
        }
      }
    }
  }
  sort(a + 1, a + c + 1, greater<LL>());
  for (int i = 1; i <= c && i <= d[x]; ++i) {
    f[x][l] += max(0LL, a[i]);
  }
  d[x] += l;
  return f[x][l];
}

int main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cin >> n;
  fill(&f[0][0], &f[n][1] + 1, -1);
  for (int i = 1; i <= n; ++i) {
    cin >> d[i];
  }
  for (int i = 1, x, y, w; i < n; ++i) {
    cin >> x >> y >> w;
    e[x].push_back({y, w}), e[y].push_back({x, w});
  }
  cout << D(1, 0, 0);
  return 0;
}
2022/7/9 21:50
加载中...