- 学术
LCT
- 2025-8-16 14:35:27 @
// Problem: CF603E Pastoral Oddities
// URL: https://www.luogu.com.cn/problem/CF603E
// Memory Limit: 250 MB
// Time Limit: 4000 ms
// 1zhiO2
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 4e5 + 7, M = 3e5 + 7;
int n, m, x[M], y[M], z[M], v[M], cnt;
priority_queue<pair<int, int>> q;
struct L {
int f[N], ch[N][2], s[N], rev[N], a[N], c[N], d[N];
#define lc ch[p][0]
#define rc ch[p][1]
#define get(p) (p == ch[f[p]][1])
#define flp(p) rev[p] ^= 1, swap(ch[p][0], ch[p][1])
#define isr(p) (ch[f[p]][0] != p && ch[f[p]][1] != p)
void upd(int p) {
s[p] = s[lc] + s[rc] + d[p] + (p <= n);
int o = a[c[lc]] > a[c[rc]] ? c[lc] : c[rc];
c[p] = a[o] > a[p] ? o : p;
}
void spd(int p) {
if (p && rev[p]) {
if (lc) flp(lc);
if (rc) flp(rc);
rev[p] = 0;
}
}
void rot(int p) {
int x = f[p], y = f[x], u = get(p), w = get(x), o = isr(x);
f[ch[p][u^1]] = x, ch[x][u] = ch[p][u^1];
f[x] = p, ch[p][u^1] = x;
upd(x), upd(p);
if ((f[p] = y) && !o) ch[y][w] = p;
}
void pr(int p) {
if (!isr(p)) pr(f[p]);
spd(p);
}
void spl(int p) {
pr(p);
for (int x = f[p]; x = f[p], !isr(p); rot(p))
if (!isr(x)) rot(get(p) == get(x) ? x : p);
}
void acc(int p) {
for (int x = 0; p; p = f[x=p])
spl(p), d[p] += s[rc], d[p] -= s[rc=x], upd(p);
}
void mkr(int p) {
acc(p), spl(p), flp(p);
}
void spt(int x, int y) {
mkr(x), acc(y), spl(y);
}
int fdr(int p) {
acc(p), spl(p);
while (lc) spd(p), p = lc;
spl(p);
return p;
}
void lnk(int u, int w) {
mkr(u), acc(w), spl(w);
cnt -= s[u] & 1, cnt -= s[w] & 1;
d[f[u]=w] += s[u], upd(w);
cnt += s[w] & 1;
}
void cut(int u, int w) {
spt(u, w);
cnt -= s[w] & 1;
f[u] = ch[w][0] = 0, upd(w);
cnt += s[u] & 1, cnt += s[w] & 1;
}
int add(int i) {
int u = ::x[i], w = ::y[i], val = ::z[i];
bool ok = 1;
if (fdr(u) == fdr(w)) { // 检查是否已连通
spt(u, w);
int o = c[w];
if (a[o] > val) { // 如果新边更优,则替换
cut(::x[o - n], o);
cut(::y[o - n], o);
v[o - n] = 1; // 标记旧边为删除
} else {
ok = 0;
}
}
if (ok) {
a[i + n] = val;
s[i + n] = c[i + n] = i + n;
lnk(u, i + n);
lnk(w, i + n);
q.push({val, i});
}
if (cnt) return -1; // 如果奇度点不为0, 无解
while (q.size()) {
int o = q.top().second;
q.pop();
if (::v[o]) continue; // 此边已被更优的边替换
cut(::x[o], o + n);
cut(::y[o], o + n);
if (cnt) { // 删除此边后破坏了欧拉回路条件
lnk(::x[o], o + n);
lnk(::y[o], o + n);
q.push({::z[o], o});
return ::z[o]; // 此边是必须的, 其权值为当前瓶颈
}
}
return 0; // 所有边都可移除, 或初始图为空
}
} l;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
cnt = n;
for (int i = 1; i <= n; i++) {
l.s[i] = 1;
l.c[i] = i;
}
for (int i = 1; i <= m; i++) {
cin >> x[i] >> y[i] >> z[i];
cout << l.add(i) << "\n";
}
return 0;
}
0 条评论
目前还没有评论...