QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#176043#7185. Poor Studentsucup-team1883TL 1ms3308kbC++144.1kb2023-09-11 08:46:282023-09-11 08:46:29

Judging History

你现在查看的是最新测评结果

  • [2023-09-11 08:46:29]
  • 评测
  • 测评结果:TL
  • 用时:1ms
  • 内存:3308kb
  • [2023-09-11 08:46:28]
  • 提交

answer

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <numeric>
#include <vector>
#include <cassert>
#include <queue>
using namespace std;

using ll = long long;
using ull = unsigned long long;

#define LOG(f...) fprintf(stderr, f)
// #define DBG(f...) printf("%3d: ", __LINE__), printf(f)
#define DBG(f...) void()
#define all(cont) begin(cont), end(cont)
#ifdef __linux__
#define getchar getchar_unlocked
#define putchar putchar_unlocked
#endif

template <class T> void read(T &x) {
  char ch; x = 0;
  int f = 1;
  while (isspace(ch = getchar()));
  if (ch == '-') ch = getchar(), f = -1;
  do x = x * 10 + (ch - '0'); while (isdigit(ch = getchar()));
  x *= f;
}
template <class T, class ...A> void read(T &x, A&... args) { read(x); read(args...); }

struct vid {
  ll v;
  int id;
  bool operator<(vid rhs) const { return v == rhs.v ? id > rhs.id : v > rhs.v; }
  bool operator==(vid rhs) const { return v == rhs.v && id == rhs.id; }
};

using min_heap = priority_queue<vid>;

const int N = 50005;
const int MAXK = 10;
const ll LLINF = 0x3f3f3f3f3f3f3f3f;

struct del_heap {
  min_heap H, D;
  void push(vid x) { H.push(x); }
  void pop(vid x) { D.push(x); }
  vid top() {
    while (!D.empty() && H.top() == D.top()) H.pop(), D.pop();
    return H.top();
  }
  bool empty() { return H.size() == D.size(); }
};

int n, m;
int cost[N][MAXK], cap[MAXK];
vid trans[MAXK][MAXK];
del_heap H[MAXK][MAXK], direct[MAXK];
ll dist[MAXK];
int src[MAXK], interm[MAXK];
int mat[N];

void initalize() {
  for (int j = 0; j < m; ++j) {
    vector<vid> seq(n);
    for (int i = 0; i < n; ++i)
      seq[i] = {cost[i][j], i};
    direct[j] = {min_heap(all(seq)), min_heap{}};
  }
}

void attach(int u, int v, bool no_direct = false) {
  DBG("attach %d %d\n", u, v);
  mat[u] = v;
  --cap[v];
  if (!no_direct)
    for (int i = 0; i < n; ++i)
      direct[i].pop({cost[u][i], u});
  for (int i = 0; i < n; ++i)
    if (i != v)
      H[v][i].push({cost[u][i] - cost[u][v], u});
}

void detach(int u, int v, bool no_direct = false) {
  DBG("detach %d %d\n", u, v);
  ++cap[v];
  if (!no_direct)
    for (int i = 0; i < n; ++i)
      direct[i].push({cost[u][i], u});
  for (int i = 0; i < n; ++i)
    if (i != v)
      H[v][i].pop({cost[u][i] - cost[u][v], u});
}

void augment() {
  for (int i = 0; i < m; ++i)
    if (direct[i].empty()) dist[i] = LLINF;
    else dist[i] = direct[i].top().v, src[i] = m + direct[i].top().id;
  for (int i = 0; i < m; ++i)
    for (int j = 0; j < m; ++j) {
      if (i != j)
        DBG("trans[%d][%d] = %lld %d\n", i, j, trans[i][j].v, trans[i][j].id);
      trans[i][j] = H[i][j].empty() ? vid{LLINF, 0} : H[i][j].top();
    }

  for (int r = 0; r < m; ++r)
    for (int i = 0; i < m; ++i)
      for (int j = 0; j < m; ++j)
        if (i != j && dist[i] + trans[i][j].v < dist[j]) {
          interm[j] = trans[i][j].id;
          dist[j] = dist[i] + trans[i][j].v;
          src[j] = i;
        }

  int u = -1;
  for (int i = 0; i < m; ++i) {
    if (cap[i] == 0) continue;
    if (u == -1 || dist[i] < dist[u]) u = i;
  }
  assert(u != -1);
  DBG("path ends at %d : dist %lld\n", u, dist[u]);

  while (true) {
    if (src[u] >= m) {
      DBG("path starts at %d\n", src[u] - m);
      attach(src[u] - m, u);
      break;
    }
    else {
      DBG("%d -> %d -> %d\n", src[u], interm[u], u);
      detach(interm[u], mat[u]);
      attach(interm[u], u);
      u = src[u];
    }
  }
}

int main() {
#ifdef LOCAL
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  read(n, m);
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j)
      read(cost[i][j]);
  for (int i = 0; i < m; ++i)
    read(cap[i]);

  initalize();
  memset(mat, -1, sizeof(mat));
  for (int i = 0; i < n; ++i)
    augment();
  ll ans = 0;
  for (int i = 0; i < n; ++i)
    DBG("%d -> %d\n", i, mat[i]);
  for (int i = 0; i < n; ++i) {
    assert(mat[i] != -1);
    ans += cost[i][mat[i]];
  }
  printf("%lld\n", ans);
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3308kb

input:

6 2
1 2
1 3
1 4
1 5
1 6
1 7
3 4

output:

12

result:

ok answer is '12'

Test #2:

score: -100
Time Limit Exceeded

input:

3 3
1 2 3
2 4 6
6 5 4
1 1 1

output:


result: