// 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 条评论

目前还没有评论...