QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#822488 | #8941. Even or Odd Spanning Tree | Suzuranovo | RE | 0ms | 0kb | C++23 | 3.3kb | 2024-12-20 13:28:02 | 2024-12-20 13:28:03 |
answer
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int inf = 1e9;
const ll INF = 1e18;
struct DSU {
vector<int> fa; DSU(int n) { init(n); }
void init(int n) { fa.resize(n + 1); iota(fa.begin(), fa.end(), 0); }
int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
void merge(int x, int y) { fa[find(x)] = find(y); }
bool same(int x, int y) { return find(x) == find(y); }
};
struct LCA {
struct node { int v; array<int, 2> w; };
node merge(const node& l, const node& r) {
return { r.v,{max(l.w[0],r.w[0]), max(l.w[1],r.w[1])} };
}
array<vector<node>, 20> s; int n;
vector<int> dep; vector<vector<array<int, 2>>> mp;
void init(int n) {
dep = vector<int>(n + 1);
mp = vector<vector<array<int, 2>>>(n + 1);
for (int i = 0, l = __lg(n); i <= l; ++i)
s[i] = vector<node>(n + 1);
} LCA(int n) { init(n); }
void add(int u, int v, int w) {
mp[u].push_back({ v,w });
mp[v].push_back({ u,w });
}
void build() {
dep[1] = 1; dfs(1);
for (int b = 1; b <= __lg(n); ++b)
for (int u = 1; u <= n; ++u)
s[b][u] = merge(s[b - 1][u],
s[b - 1][s[b - 1][u].v]);
}
void dfs(int u) {
for (auto [v, w] : mp[u]) {
if (v == s[0][u].v) continue;
dep[v] = dep[u] + 1;
s[0][v] = { u,-inf,-inf };
s[0][v].w[w & 1] = w;
dfs(v);
}
}
node query(int u, int v) {
if (dep[u] < dep[v]) swap(u, v);
node res = { u,-inf,-inf };
while (dep[u] > dep[v]) {
auto& lst = s[__lg(dep[u] - dep[v])][u];
u = lst.v;
res = merge(res, lst);
}
if (u == v) return res;
for (int b = __lg(dep[u]); b >= 0; --b) {
auto& uf = s[b][u];
auto& vf = s[b][v];
if (uf.v == vf.v) continue;
res = merge(res, merge(uf, vf));
u = uf.v; v = vf.v;
}
return merge(res, merge(s[0][u], s[0][v]));
}
};
void solve() {
int n, m; cin >> n >> m;
vector<array<int, 3>> e(m);
// 注意次序
for (auto& [w, u, v] : e) cin >> u >> v >> w;
sort(e.begin(), e.end());
DSU d(n); LCA l(n); ll sum = 0;
vector<bool> used(m); int cnt = 0;
for (int i = 0; i < m; ++i) {
auto [w, u, v] = e[i];
if (d.same(u, v)) continue;
d.merge(u, v); sum += w;
used[i] = true; ++cnt;
l.add(u, v, w);
}
if (cnt < n - 1) { cout << "-1 -1\n"; return; }
l.build();
array<ll, 2> ans{ INF,INF };
int tg = sum & 1;
ans[tg] = sum;
for (int i = 0; i < m; ++i) {
if (used[i]) continue;
auto [w, u, v] = e[i];
auto mx = l.query(u, v).w;
ll cur = sum + w;
// 删去一个异值 以到达答案
if ((cur & 1) == tg) cur -= mx[1];
else cur -= mx[0];
ans[!tg] = min(ans[!tg], cur);
}
if (ans[0] == INF) ans[0] = -1;
if (ans[1] == INF) ans[1] = -1;
cout << ans[0] << " " << ans[1] << "\n";
}
int main() {
cin.tie(nullptr)->sync_with_stdio(0);
int t = 1; cin >> t;
while (t--)
solve();
return 0;
}
详细
Test #1:
score: 0
Runtime Error
input:
3 2 1 1 2 5 3 1 1 3 1 4 4 1 2 1 1 3 1 1 4 1 2 4 2