n^3/w WA 85pts 求助
查看原帖
n^3/w WA 85pts 求助
392400
Anamnesis楼主2022/11/2 11:46

n3w\frac{n^3}{w},WA on 7, 13, 18. 在 infoj 也是 85pts,输出比标准答案要小。

不太明白哪里错了……看讨论区有说 WA85 是图不连通的原因,但我感觉图不连通并不影响这个做法,可能是我失智了?求助/kk

#include <bits/stdc++.h>
#define Imax(x, y) ((x) > (y) ? (x) : (y))
#define Imin(x, y) ((x) < (y) ? (x) : (y))
#define Iabs(x) ((x) > 0 ? (x) : (-(x)))
#define all(x) x.begin(), x.end()
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++);
char buf[1 << 21], *p1 = buf, *p2 = buf;
inline long long read() { 
  long long x = 0, f = 1; char ch = getchar();
  while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
  while (ch >= '0' && ch <= '9') { x = x * 10 + ch - 48; ch = getchar(); }
  return x * f;
}
typedef long long ll;
using namespace std;

int main() {
  int n = read(), m = read(), k = read();
  vector<pair<ll, int>> p(n);
  vector<int> mp(n);
  vector<vector<int>> E(n);
  for (int i = 1; i < n; ++i)
    p[i].first = read(), p[i].second = i;
  p[0].first = p[0].second = 0;
  sort(p.rbegin(), p.rend());
  for (int i = 0; i < n; ++i)
    mp[p[i].second] = i;
  for (int i = 0; i < m; ++i) {
    int u = read(), v = read();
    E[mp[u - 1]].push_back(mp[v - 1]);
    E[mp[v - 1]].push_back(mp[u - 1]);
  }
  // for (int i = 0; i < n; ++i)
  //   printf("[%d -> %d] %d\n", i, p[i].second, p[i].first);
  const int H = mp[0];

  vector<bitset<2500>> ok(n);
  vector<int> vis(n);
  function<void(int, int)> dfs = [&](int st, int dep) {
    vis[st] = 1;
    if (dep >= k + 1) // k = 0 : dep = 1
      return;
    for (int ed : E[st]) {
      if (!vis[ed])
        dfs(ed, dep + 1);
    }
  };
  for (int i = 0; i < n; ++i) {
    fill(all(vis), 0);
    dfs(i, 0);
    for (int j = 0; j < n; ++j)
      if (vis[j])
        ok[i].set(j);
  }

  ll ans = 0;
  for (int B = 0; B < n; ++B) {
    if (B != H)
      for (int C = 0; C < n; ++C) {
        if (C != H && C != B && ok[B][C]) {
          auto okA = ok[H] & ok[B];
          auto okD = ok[H] & ok[C];

          int A = okA._Find_first();
          while (A == H || A == B || A == C) A = okA._Find_next(A);
          if (A == 2500)
            continue;
          int D = okD._Find_first();
          while (D == H || D == B || D == C || D == A) D = okD._Find_next(D);
          if (D == 2500)
            continue;

          ll res = p[A].first + p[B].first + p[C].first + p[D].first;
          // if (ans <= res)
          //   printf("Got: %d %d %d %d, ans = %lld\n", p[A].second + 1, p[B].second + 1, p[C].second + 1, p[D].second + 1, res);
          ans = Imax(res, ans);
        }
      }
  }
  printf("%lld\n", ans);

  return 0;
}
2022/11/2 11:46
加载中...