QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#697660#7069. FarmSunsetGlow95WA 95ms34564kbC++144.7kb2024-11-01 15:15:442024-11-01 15:15:47

Judging History

This is the latest submission verdict.

  • [2024-11-01 15:15:47]
  • Judged
  • Verdict: WA
  • Time: 95ms
  • Memory: 34564kb
  • [2024-11-01 15:15:44]
  • Submitted

answer

#include <bits/stdc++.h>
using namespace std;

const int MXN = 100005;
const int MXM = 500005;
const int MXQ = 20;
const int MXP = MXQ * 8;
const int MXE = MXP + MXQ * 2;
const int INF = 1000000000;
const int MXLG = 18;
int N, M, Q, con[MXQ][2], fa[MXN];
tuple<int, int, int, int> oes[MXM], ves[MXE];
bool emark[MXM], vmark[MXN], chosen[MXM];
vector<pair<int, int>> te[MXN];
int dfn[MXN], col[MXN], jump[MXN][MXLG], mxe[MXN][MXLG], dep[MXN];
int stk[MXP], top(-1), pid[MXP], rpid[MXN], P, E;
int ecnt, esum, ans(INF);

int read() {
  int x(0), c(getchar());
  while (c < '0' || c > '9') c = getchar();
  while (c >= '0' && c <= '9') x = x * 10 + (c - '0'), c = getchar();
  return x;
}

int find(int x) { return x ^ fa[x] ? fa[x] = find(fa[x]) : x; }

void prework(int p, int f, int w, int c) {
  static int did = 0;
  col[p] = c, dfn[p] = did++;
  jump[p][0] = f, mxe[p][0] = w;
  for (int i(1); ~jump[p][i - 1]; ++i) {
    jump[p][i] = jump[jump[p][i - 1]][i - 1];
    mxe[p][i] = max(mxe[p][i - 1], mxe[jump[p][i - 1]][i - 1]);
  }
  for (auto e : te[p]) {
    if (e.first == f) continue;
    dep[e.first] = dep[p] + 1;
    prework(e.first, p, e.second, c);
  }
}

int getlca(int x, int y) {
  if (dep[x] < dep[y]) swap(x, y);
  for (int i(MXLG - 1); ~i; --i)
    if (((dep[x] - dep[y]) >> i) & 1) x = jump[x][i];
  if (x == y) return x;
  for (int i(MXLG - 1); ~i; --i)
    if (jump[x][i] != jump[y][i]) x = jump[x][i], y = jump[y][i];
  return jump[x][0];
}
void addedge(int x, int y) {
  // y is an ancestor of x
  int v(-1);
  for (int p(x), i(MXLG - 1); ~i; --i)
    if (((dep[x] - dep[y]) >> i) & 1)
      v = max(v, mxe[p][i]), p = jump[p][i];
  --ecnt, esum -= v;
  ves[E++] = make_tuple(v, rpid[x], rpid[y], -1);
//cout << "tree1" << endl;
}

int main() {
  // input
  N = read(), M = read();
  for (int i(0), u(0), v(0), w(0); i != M; ++i)
    u = read() - 1, v = read() - 1, w = read(),
    oes[i] = make_tuple(w, u, v, i);
  Q = read();
  for (int i(0); i != Q; ++i)
    emark[con[i][0] = read() - 1] = emark[con[i][1] = read() - 1] = true;

  // get the min spanning forest of unmarked edges
  sort(oes, oes + M);
  for (int i(0); i != N; ++i) fa[i] = i;
  for (int i(0); i != M; ++i) {
    auto e(oes[i]);
    int x(get<1>(e)), y(get<2>(e)), w(get<0>(e));
    if (emark[get<3>(e)]) {
      vmark[x] = vmark[y] = true;
      continue;
    }
    if (find(x) == find(y)) continue;
    fa[find(x)] = find(y);
    ++ecnt, esum += w;
    te[x].emplace_back(y, w);
    te[y].emplace_back(x, w);
  }

  // get the virtual forest of marked vertices, and construct the edge set
  memset(dfn, -1, sizeof dfn);
  memset(jump, -1, sizeof jump);
  memset(rpid, -1, sizeof rpid);
  for (int i(0); i != N; ++i) {
    if (dfn[i] == -1) prework(i, -1, INF, i);
    if (vmark[i]) rpid[i] = P, pid[P++] = i;
  }
  sort(pid, pid + P, [](int x, int y) -> bool { return dfn[x] < dfn[y]; });
  for (int i(0), op(P); i != op; ++i) {
    int p(pid[i]);
    if (~top && col[stk[top]] != col[p]) {
      for (int lst(stk[top--]); ~top; lst = stk[top--])
        addedge(lst, stk[top]);
    }
    if (top == -1) {
      stk[++top] = p;
      continue;
    }
    int f(getlca(stk[top], p)), lst(-1);
    while (dep[stk[top]] > dep[f]) {
      if (~lst) addedge(lst, stk[top]);
      lst = stk[top--];
    }
    if (top == -1 || stk[top] != f) rpid[f] = P, pid[P++] = f, stk[++top] = f;
    if (~lst) addedge(lst, stk[top]);
    stk[++top] = p;
  }
  if (~top)
    for (int lst(stk[top--]); ~top; lst = stk[top--])
      addedge(lst, stk[top]);
  sort(pid, pid + P,
      [](int x, int y) -> bool { return rpid[x] < rpid[y]; });
  for (int i(0); i != M; ++i) {
    if (!emark[get<3>(oes[i])]) continue;
    auto e(oes[i]);
    ves[E++] = make_tuple(get<0>(e), rpid[get<1>(e)], rpid[get<2>(e)], get<3>(e));
  }
  sort(ves, ves + E);

  // try the choices one by one
  for (int i(0); i != (1 << Q); ++i) {
    for (int j(0); j != P; ++j) fa[j] = j;
    for (int j(0); j != Q; ++j)
      chosen[con[j][(i >> j) & 1]] = true;
    int tcnt(ecnt), tsum(esum);
    for (int j(0); j != E; ++j) {
      if (get<3>(ves[j]) == -1 || !chosen[get<3>(ves[j])]) continue;
      tsum += get<0>(ves[j]);
      int x(find(get<1>(ves[j]))), y(find(get<2>(ves[j])));
      if (x != y) fa[x] = y, ++tcnt;
    }
    for (int j(0); j != E; ++j) {
      int x(find(get<1>(ves[j]))), y(find(get<2>(ves[j])));
      if (x == y) continue;
      tsum += get<0>(ves[j]);
      fa[x] = y, ++tcnt;
    }
    if (tcnt == N - 1) ans = min(ans, tsum);
    for (int j(0); j != Q; ++j)
      chosen[con[j][(i >> j) & 1]] = false;
  }

  if (ans == INF) puts("mumuyibarenkoumumumu");
  else printf("%d\n", ans);
  return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 18536kb

input:

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

output:

11

result:

ok single line: '11'

Test #2:

score: -100
Wrong Answer
time: 95ms
memory: 34564kb

input:

100000 500000
2516 13348 191
37713 25720 216
41568 13765 877
2116 27917 895
76904 65435 37
73053 24687 44
97127 44338 700
2251 85769 378
95166 20208 42
59303 57463 158
26863 18030 31
58613 6818 2
15455 18106 254
3232 13720 610
85677 16778 650
25618 72746 813
80365 162 47
10930 7403 645
79272 54568 6...

output:

mumuyibarenkoumumumu

result:

wrong answer 1st lines differ - expected: '-1', found: 'mumuyibarenkoumumumu'