比赛 寒假集训5 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 魔法森林 最终得分 100
用户昵称 李金泽 运行时间 2.241 s
代码语言 C++ 内存使用 7.50 MiB
提交时间 2026-03-01 10:20:14
显示代码纯文本
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define N 50005
#define M 100005
#define lc(x) t[x].ch[0]
#define rc(x) t[x].ch[1]
#define fa(x) t[x].fa
#define ma(x) t[x].ma
#define mb(x) t[x].mb
#define id(x) t[x].id
#define ta(x) t[x].ta
#define int long long
#define fo(i,l,r) for(int i=l;i<=r;i++)
#define rf(i,r,l) for(int i=r;i>=l;i--)
using namespace std;
int n,m,k,f[N],ans=-1,op,x,y,z;const int inf=1e18;
struct tree{int ch[2],fa,ma,mb,id;bool ta;}t[N+M];
struct edge{int x,y,a,b;bool operator<(edge y){return a<y.a;}}e[M];
void swap(int &x,int &y){int t=x;x=y;y=t;}
int max(int x,int y){return x>y?x:y;}
int min(int x,int y){return x<y?x:y;}
int fd(int x){return x^f[x]?f[x]=fd(f[x]):x;}
void mg(int x,int y){f[fd(x)]=fd(y);}
void pu(int x)
{
    ma(x)=max(e[id(x)].a,max(ma(lc(x)),ma(rc(x))));
    mb(x)=e[id(x)].b>e[mb(lc(x))].b?id(x):mb(lc(x));
    mb(x)=e[mb(x)].b>e[mb(rc(x))].b?mb(x):mb(rc(x));
}
void rv(int x){swap(lc(x),rc(x));ta(x)^=1;}
void pd(int x){if(ta(x)){rv(lc(x));rv(rc(x));ta(x)=0;}}
bool nt(int x){int y=fa(x);return lc(y)==x||rc(y)==x;}
void push(int x){if(nt(x))push(fa(x));pd(x);}
void ro(int x)
{
    int y=fa(x),g=fa(y),k=rc(y)==x;
    if(nt(y))t[g].ch[rc(g)==y]=x;
    fa(x)=g;
    if(t[x].ch[k^1])fa(t[x].ch[k^1])=y;
    t[y].ch[k]=t[x].ch[k^1];
    fa(y)=x;t[x].ch[k^1]=y;
    pu(y);pu(x);
}
void splay(int x)
{
    push(x);
    for(int y,g;nt(x);ro(x))
    {
        y=fa(x);g=fa(y);
        if(nt(y))ro((rc(y)==x)^(rc(g)==y)?x:y);
    }
}
void access(int x)
{
    for(int y=0;x;x=fa(x))
    {
        splay(x);
        rc(x)=y;
        pu(x);y=x;
    }
}
void makeroot(int x)
{
    access(x);
    splay(x);
    rv(x); 
}
void split(int x,int y)
{
    makeroot(x);
    access(y);
    splay(y);
}
int find(int x)
{
    access(x);splay(x);
    while(lc(x))x=lc(x);
    splay(x);
    return x;
}
void cut(int x,int y)
{
    makeroot(x);access(y);splay(y);
    fa(x)=lc(y)=0;
}
void link(int i)
{
    x=e[i].x;y=e[i].y;
    makeroot(x);
    if(fd(x)!=fd(y))
    {
        mg(x,y);
        fa(x)=i+n;fa(i+n)=y;
    }
    else 
    {
        access(y);splay(y);
        if(e[i].b<e[mb(y)].b)
        {
            z=mb(y);
            cut(e[z].x,z+n);cut(z+n,e[z].y);
            makeroot(x);fa(x)=i+n;fa(i+n)=y;
        }
    }
    if(fd(1)==fd(n))
        split(1,n),ans=min(~ans?ans:inf,ma(n)+e[mb(n)].b);
}
int read(){
    int sum=0;bool f=0;char c=getchar();
    for(;c<48||c>57;c=getchar())if(c==45)f=1;
    for(;c>=48&&c<=57;c=getchar())sum=sum*10+(c&15);
    return f?-sum:sum;
}
signed main(){
    freopen("magicalforest.in","r",stdin);freopen("magicalforest.out","w",stdout);
    n=read();m=read();
    fo(i,1,n)f[i]=i;
    fo(i,1,m)e[i]={read(),read(),read(),read()},id(i+n)=i,ma(i+n)=e[i].a,mb(i+n)=i;
    sort(e+1,e+m+1);
    fo(i,1,m)link(i);
    printf("%lld",ans);
    return 0;
}