NOI2014B. Magical Forest

Question description

In order to get the true biography of the master of calligraphy, Xiao E made up his mind to visit the hermit living in the magic forest.

The magic forest can be viewed as a network containing NNN nodesMM_An undirected graph with M edges, with node labels1,…,N1,\ldots,N1,,N , edge labels are1,…,M1,\ldots,M1,,M. _ At the beginning, Little E’s classmate was at node111 , the hermit lives inNNNode N. Little E needs to pass through this magical forest to visit the hermit.

There are some monsters living in the enchanted forest. Whenever someone passes by an edge, the monsters on that edge will attack them. Fortunately, at 11There are two kinds of guardian spirits living in Node 1 : AAType A guardian elf andBBType B guardian elf. Little E can use their power to achieve his own goals.

As long as Little E brings enough guardian elves, the monsters will not attack. Specifically, each edge EiE_i in the undirected graphEiContains two weights AiA_iAiBiB_iBi. If the number of A-type guardian spirits carried on the body is not less than AiA_iAi, and BBThe number of type B guardian elves is not less thanBiB_iBi, the monsters on this edge will not attack people passing through this edge. If and only if no monsters on either side attack Little E during the process of passing through this magical forest, he can successfully find the hermit.

Since carrying guardian elves is a very troublesome matter, Little E wants to know the minimum number of guardian elves that are needed to successfully visit the hermit. The total number of guardian elves is AANumber of A -type guardian spirits andBBThe total number of B -type guardian elves.

Input format

The first line contains two integers N,MN,MN,M , indicating that the undirected graph has a total ofNNN nodes,MMM sides.
NextMMLine M , iiLine i contains four positive integersXi, Yi, Ai, BiX_i, Y_i, A_i, B_iXi,Yi,Ai,Bi, description iii undirected edges. Among themXiX_iXiYiYiY_i _Yiare the labels of the two endpoints of the edge, AiA_iAiBiB_iBiThe meaning is as stated in the title.

Note : The data may contain multiple edges and self-loops.

Output format

Output an integer per line: If Little E can successfully visit the hermit, output the minimum number of guardian elves that Little E needs to carry;
if Little E cannot visit the hermit no matter what, output " -1" (without quotation marks).

Enter data 1

4 5
1 2 19 1
2 3 8 12
2 4 12 15
1 3 17 8
3 4 1 17
Copy

Output data 1

32
Copy

Enter data 2

3 1
1 2 1 1
Copy

Output data 2

-1
Copy

Data range and prompts

For all data, 2≤n≤50000, 0≤m≤100000, 1≤ai,bi≤500002 \leq n \leq 50000,\ 0 \leq m \leq 100000,\ 1 \leq a_i ,b_i \leq 500002n50000, 0m100000, 1ai,bi50000

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
inline int read() {
    
    
    int res = 0; bool bo = 0; char c;
    while (((c = getchar()) < '0' || c > '9') && c != '-');
    if (c == '-') bo = 1; else res = c - 48;
    while ((c = getchar()) >= '0' && c <= '9')
        res = (res << 3) + (res << 1) + (c - 48);
    return bo ? ~res + 1 : res;
}
const int N = 2e5 + 5;
int n, m, fa[N], lc[N], rc[N], rev[N], que[N], len, val[N], sm[N],
f[N];
struct cyx {
    
    int a, b, x, y;} ask[N];
int cx(int x) {
    
    
    if (f[x] != x) f[x] = cx(f[x]);
    return f[x];
}
void zm(int x, int y) {
    
    
    int ix = cx(x), iy = cx(y);
    if (ix != iy) f[iy] = ix;
}
bool comp(cyx a, cyx b) {
    
    return a.y < b.y;}
int which(int x) {
    
    return rc[fa[x]] == x;}
bool is_root(int x) {
    
    
    return !fa[x] || (lc[fa[x]] != x && rc[fa[x]] != x);
}
void upt(int x) {
    
    
    sm[x] = x;
    if (lc[x] && val[sm[lc[x]]] > val[sm[x]]) sm[x] = sm[lc[x]];
    if (rc[x] && val[sm[rc[x]]] > val[sm[x]]) sm[x] = sm[rc[x]];
}
void down(int x) {
    
    
    if (rev[x]) {
    
    
        swap(lc[x], rc[x]);
        if (lc[x]) rev[lc[x]] ^= 1;
        if (rc[x]) rev[rc[x]] ^= 1;
        rev[x] = 0;
    }
} 
void rotate(int x) {
    
    
    int y = fa[x], z = fa[y], b = lc[y] == x ? rc[x] : lc[x];
    if (z && !is_root(y)) (lc[z] == y ? lc[z] : rc[z]) = x;
    fa[x] = z; fa[y] = x; b ? fa[b] = y : 0;
    if (lc[y] == x) rc[x] = y, lc[y] = b;
    else lc[x] = y, rc[y] = b; upt(y); upt(x);
}
void splay(int x) {
    
    
    int i, y; que[len = 1] = x;
    for (y = x; !is_root(y); y = fa[y]) que[++len] = fa[y];
    for (i = len; i >= 1; i--) down(que[i]);
    while (!is_root(x)) {
    
    
        if (!is_root(fa[x])) {
    
    
            if (which(x) == which(fa[x])) rotate(fa[x]);
            else rotate(x);
        }
        rotate(x);
    }
    upt(x);
}
void Access(int x) {
    
    
    int y;
    for (y = 0; x; y = x, x = fa[x]) {
    
    
        splay(x); rc[x] = y;
        if (y) fa[y] = x; upt(x);
    }
}
int Find_Root(int x) {
    
    
    Access(x); splay(x);
    while (down(x), lc[x]) x = lc[x];
    splay(x); return x;
}
void Make_Root(int x) {
    
    
    Access(x); splay(x);
    rev[x] ^= 1;
}
void Link(int x, int y) {
    
    
    Make_Root(x); fa[x] = y;
}
void Cut(int x, int y) {
    
    
    Make_Root(x); Access(y); splay(y);
    lc[y] = 0; fa[x] = 0; upt(y);
}
int Select(int x, int y) {
    
    
    Make_Root(x); Access(y); splay(y);
    return sm[y];
}
int main() {
    
    
    int i, ans = 2e9; n = read(); m = read();
    for (i = 1; i <= m; i++)
        ask[i].a = read(), ask[i].b = read(),
        ask[i].x = read(), ask[i].y = read();
    sort(ask + 1, ask + m + 1, comp);
    for (i = 1; i <= n + m; i++) f[i] = sm[i] = i;
    for (i = n + 1; i <= n + m; i++) val[i] = ask[i - n].x;
    for (i = 1; i <= m; i++) {
    
    
        int u = ask[i].a, v = ask[i].b; bool flag = 1;
        if (cx(u) == cx(v)) {
    
    
            int w = Select(u, v);
            if (val[w] > ask[i].x)
                Cut(ask[w - n].a, w), Cut(w, ask[w - n].b);
            else flag = 0;
        }
        else zm(u, v); if (flag) Link(u, i + n), Link(i + n, v);
        if (cx(1) == cx(n))
            ans = min(ans, ask[i].y + val[Select(1, n)]);
    }
    if (ans < 2e9) printf("%d\n", ans);
    else printf("-1\n");
    return 0;
}

Guess you like

Origin blog.csdn.net/yaosichengalpha/article/details/132450288