QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#697660 | #7069. Farm | SunsetGlow95 | WA | 95ms | 34564kb | C++14 | 4.7kb | 2024-11-01 15:15:44 | 2024-11-01 15:15:47 |
Judging History
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'