记录编号 272600 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOI 2014]魔法森林 最终得分 100
用户昵称 GravatarFmuckss 是否通过 通过
代码语言 C++ 运行时间 2.263 s
提交时间 2016-06-17 16:41:29 内存使用 10.23 MiB
显示代码纯文本
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 10;
const int inf = 1e9;

int n, m;
int val[maxn << 1]; 

#define is_num(x) (x >= '0' and x <= '9')

inline int get_num() {
	int ans = 0;
	char tmp = getchar();
	while(!is_num(tmp)) tmp = getchar();
	while( is_num(tmp)) {
		ans = ans * 10 + tmp - '0';
		tmp = getchar();
	}
	return ans;
}

struct link_cut_tree {
private:
	struct node {
		int ls, rs, fa;
		int mxid;
		bool revc;
		node() { ls = rs = fa = revc = mxid = 0; }
	}ns[maxn << 2];
	
	inline void update(int tar) {
		if(!tar) return;
		int mxid = tar;
		int lsid = ns[ns[tar].ls].mxid, rsid = ns[ns[tar].rs].mxid;
		if(lsid and val[lsid] > val[mxid]) mxid = lsid;
		if(rsid and val[rsid] > val[mxid]) mxid = rsid;
		ns[tar].mxid = mxid;
	}
	
	inline bool is_root(int tar) {
		int fa = ns[tar].fa;
		return ns[fa].rs != tar and ns[fa].ls != tar;
	}
	
	inline void make_revc(int tar) {
		if(!tar) return;
		swap(ns[tar].ls, ns[tar].rs);
		
		ns[tar].revc ^= 1;
	}
	
	inline void push_down(int tar) {
		if(!tar) return;
		if(ns[tar].revc) {
			make_revc(ns[tar].ls);
			make_revc(ns[tar].rs);
			ns[tar].revc ^= 1;
		}
	}
	
	inline void zig(int &tar) {
		int fa = ns[tar].fa;
		if(ns[ns[fa].fa].ls == fa) ns[ns[fa].fa].ls = tar;
		if(ns[ns[fa].fa].rs == fa) ns[ns[fa].fa].rs = tar;
		ns[tar].fa = ns[fa].fa;
		ns[ns[tar].rs].fa = fa;
		ns[fa].ls = ns[tar].rs;
		ns[tar].rs = fa, ns[fa].fa = tar;
		update(fa);
	} 
	
	inline void zag(int &tar) {
		int fa = ns[tar].fa;
		if(ns[ns[fa].fa].ls == fa) ns[ns[fa].fa].ls = tar;
		if(ns[ns[fa].fa].rs == fa) ns[ns[fa].fa].rs = tar;
		ns[tar].fa = ns[fa].fa;
		ns[ns[tar].ls].fa = fa;
		ns[fa].rs = ns[tar].ls;
		ns[tar].ls = fa, ns[fa].fa = tar;
		update(fa);
	}
	
	inline void splay(int now) {
		int fa;
		push_down(now);
		while(!is_root(now)) {
			fa = ns[now].fa;
			push_down(ns[fa].fa), push_down(fa), push_down(now);
			if(is_root(fa)) {
				ns[fa].ls == now ? zig(now) : zag(now);
				break;
			}
			else {
				if(ns[ns[fa].fa].ls == fa) ns[fa].ls == now ? zig(fa) : zag(now), zig(now);
				else ns[fa].rs == now ? zag(fa) : zig(now), zag(now);
			}
		}
		update(now);
	}
	
	inline void access(int tar) {
		int la = 0;
		while(tar) {
			splay(tar);
			ns[tar].rs = la;
			update(tar);
			la = tar;
			tar = ns[tar].fa;
		}
	}

	inline void make_root(int tar) {
		access(tar);
		splay(tar);
		make_revc(tar);
	}
	
	inline int find_root(int tar) {
		access(tar);
		splay(tar);
		while(ns[tar].ls) {
			push_down(tar);
			tar = ns[tar].ls;
		}
		splay(tar);
		return tar;
	}
public:
	inline void link(int u, int v) {
		make_root(v);
		ns[v].fa = u;
	}
	
	inline void cut(int u, int v) {
		make_root(u); access(v); splay(u);
		ns[u].rs = 0, ns[v].fa = 0;
		update(u);
	}
	
	inline bool is_connect(int u, int v) {
		return find_root(u) == find_root(v);
	}
	
	inline int query_mx(int u, int v) {
		make_root(u); access(v); splay(v);
		return ns[v].mxid;
	}
}lct;

struct edge {
	int fr, to, va, vb;
	edge() {}
	edge(int fr_, int to_, int va_, int vb_) { fr = fr_, to = to_, va = va_, vb = vb_; }
	
	bool operator < (const edge &b) const {
		return va == b.va ? vb < b.vb : va < b.va;
	}
}e[maxn];

inline void read() {
	n = get_num();
	m = get_num();
	int fr, to, va, vb;
	for(int i = 1; i <= m; i++) {
		fr = get_num(); to = get_num();
		va = get_num(); vb = get_num();
		e[i] = edge(fr, to, va, vb);
	}
}

inline void add_edge(int i) {
	val[n + i] = e[i].vb;//只有访问i + n的时候才是有效访问 
	lct.link(n + i, e[i].to);
	lct.link(n + i, e[i].fr);
}

inline void solve() {
	sort(e + 1, e + m + 1);
	int ans = inf;
	
	for(int i = 1; i <= m; i++) {
		int fr = e[i].fr, to = e[i].to;
		if(lct.is_connect(fr, to)) {
			int tar = lct.query_mx(fr, to);
			if(val[tar] > e[i].vb) {
				lct.cut(tar, e[tar - n].fr);
				lct.cut(tar, e[tar - n].to);
				add_edge(i);
			}
		} else {
			add_edge(i);
		}
		
		if(lct.is_connect(1, n)) ans = min(ans, e[i].va + val[lct.query_mx(1, n)]);
	}
	
	printf("%d\n", ans == inf ? -1 : ans);
}

int main() {
	freopen("magicalforest.in",  "r", stdin);
	freopen("magicalforest.out", "w", stdout);
	read();
	solve();
	return 0;
}