QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#697656#7069. FarmSunsetGlow95RE 0ms0kbC++144.8kb2024-11-01 15:15:292024-11-01 15:15:39

Judging History

This is the latest submission verdict.

  • [2024-11-01 15:15:39]
  • Judged
  • Verdict: RE
  • Time: 0ms
  • Memory: 0kb
  • [2024-11-01 15:15:29]
  • 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() {
  freopen("bridge.in", "r", stdin);
  freopen("bridge.out", "w", stdout);
  // 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: 0
Dangerous Syscalls

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:


result: