There are two weights for this problem. We put all the edges at the right value A, the rest of the edges as points into a LCT. The position of the maximum weighted point for each node is enumerated all edges if u, the general clause of the V-Link deletes the largest edge to join the edge
Otherwise, join this side directly when you find 1 and n Connect, update the answer.
When you open an array, you get Val and Max into bool, and you're drunk. Orz
#include <cstdio> #include <algorithm> #include <cstring> #include <iostream> #include <queu
e> #define SF scanf #define PF printf using namespace std;
typedef long Long LL;
const int MAXN = 50000;
const int MAXM = 100000;
const int maxnode = 150000;
const int INF = 1234567890;
struct LCT {int ch[maxnode+10][2], fa[maxnode+10], max[maxnode+10];
int val[maxnode+10], q[maxnode+10];
BOOL REV[MAXNODE+10];
BOOL IsRoot (int x) {return ch[fa[x]][0]! = x && ch[fa[x]][1]! = x;
} void up (int x) {int ls = ch[x][0], rs = ch[x][1];
MAX[X] = x;
if (Val[max[ls]] > val[max[x]]) max[x] = Max[ls];
if (Val[max[rs]] > val[max[x]]) max[x] = Max[rs];
} void Pushdown (int x) {int &ls = ch[x][0], &rs = ch[x][1];
if (Rev[x]) {rev[x] ^= 1; rev[ls] ^= 1; rev[rs] ^= 1;
Swap (LS, RS);
}} void Rotate (int x) {int y = fa[x], z = fa[y];
BOOL D = x = = Ch[y][0];
if (!isroot (y)) Ch[z][y = = Ch[z][1]] = x; FA[X] = Z; Fa[y] = x;
Fa[ch[x][d]] = y; CH[Y][!D] = ch[x][d];
Ch[x][d] = y;
Up (y); } void Splay (int x) {int top = 0;
Q[++top] = x;
for (int i = x;!isroot (i); i = Fa[i]) q[++top] = Fa[i];
for (int i = top; i; i--) pushdown (Q[i]);
while (!isroot (x)) {int y = fa[x];
if (!isroot (y)) Rotate ((ch[y][0] = = x ^ ch[fa[y]][0] = = y)? x:y);
Rotate (x);
} up (x);
} void Access (int x) {int t = 0;
while (x) {splay (x);
CH[X][1] = t; t = x;
x = Fa[x];
}} void Makeroot (int x) {access (x); splay (x); rev[x] ^= 1;
} void link (int x, int y) {makeroot (x); fa[x] = y;
} void Cut (int x, int y) {makeroot (x); Access (y); splay (y); ch[y][0] = fa[x] = 0;
} int query (int x, int y) {makeroot (x); Access (y); splay (y); return max[y];
}} SP;
int fa[maxnode+10], n, m, ans = INF;
int find (int x) {return fa[x] = = x X:fa[x] = find (fa[x]), struct Node {int u, V, a, B;
BOOL operator < (const Node &t) Const {return a < T.A;
}} E[MAXM+10];
int main () { SF ("%d%d", &n, &m);
for (int i = 1; I <= n; i++) fa[i] = i;
for (int i = 1; I <= m; i++) SF ("%d%d%d%d", &e[i].u, &E[I].V, &E[I].A, &e[i].b);
Sort (e+1, e+1+m);
for (int i = 1; I <= m; i++) {sp.val[n+i] = e[i].b; Sp.
Max[n+i] = n+i;
} for (int i = 1; I <= m; i++) {int u = e[i].u, v = e[i].v, wt = E[I].B;
int x = Find (u), y = find (v);
if (x! = y) {fa[x] = y; Sp.link (U, n+i);
Sp.link (V, n+i);
} else {int t = sp.query (U, v);
if (WT < SP.VAL[T]) {sp.cut (e[t-n].u, T); Sp.cut (E[T-N].V, T); Sp.link (U, n+i);
Sp.link (V, n+i);
}} if (find (1) = = Find (n)) ans = min (ans, sp.val[sp.query (1, N)] + e[i].a);
} PF ("%d", ans = = INF. -1:ans); }