题解:

和上一题差不多的一个思路

首先按照ai排序

然后一条条bi加进来,对bi做最小生成树(lct)

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m,ans=2e9,fa[N],val[N],f[N],ch[N][2],num[N],rev[N];
struct hp{int x,y,a,b;}e[N];
int cmp(hp x,hp y){return x.a<y.a||(x.a==y.a&&x.b<y.b);}
int find(int x){if (x==fa[x]) return x;return fa[x]=find(fa[x]);}
int get(int x){return ch[f[x]][1]==x;}
int isroot(int x){return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;}
void update(int x)
{
    num[x]=x;
    if (ch[x][0]&&val[num[ch[x][0]]]>val[num[x]])num[x]=num[ch[x][0]];
    if (ch[x][1]&&val[num[ch[x][1]]]>val[num[x]])num[x]=num[ch[x][1]];
}
void pushdown(int x)
{
    if (rev[x])
     {
        swap(ch[x][0],ch[x][1]);
        rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;rev[x]=0;
     }
}
void rotate(int x)
{
    int y=f[x],z=f[y],k=get(x);
    if (!isroot(y)) ch[z][ch[z][1]==y]=x;f[x]=z;
    ch[y][k]=ch[x][k^1];f[ch[y][k]]=y;
    ch[x][k^1]=y;f[y]=x;
    update(y);update(x);
}
void down(int x){if (!isroot(x))down(f[x]);pushdown(x);}
void splay(int x)
{
    down(x);
    for (int fa;!isroot(x);rotate(x))
     if (!isroot(fa=f[x]))rotate((get(x)==get(fa))?fa:x);
}
void access(int x){for (int t=0;x;t=x,x=f[x])splay(x),ch[x][1]=t,update(x);}
void reverse(int x){access(x);splay(x);rev[x]^=1;}
void link(int x,int y){reverse(x);f[x]=y;splay(x);}
void cut(int x,int y){reverse(x);access(y);splay(y);ch[y][0]=f[x]=0;}
int query(int x,int y){reverse(x);access(y);splay(y);return num[y];}
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++)scanf("%d%d%d%d",&e[i].x,&e[i].y,&e[i].a,&e[i].b);
    sort(e+1,e+m+1,cmp);
    for (int i=1;i<=m;i++)val[n+i]=e[i].b;
    for (int i=1;i<=n;i++)fa[i]=i;
    for (int i=1;i<=m;i++)
     {
        int fx=find(e[i].x),fy=find(e[i].y);
        if (fx!=fy)link(e[i].x,n+i),link(n+i,e[i].y),fa[fx]=fy;
        else
         {
            int k=query(e[i].x,e[i].y);
            if (val[k]>e[i].b)
             {
                cut(e[k-n].x,k);cut(k,e[k-n].y);
                link(e[i].x,n+i);link(n+i,e[i].y);
             }
         }
        if (find(1)==find(n))ans=min(ans,e[i].a+val[query(1,n)]);
     }
    if (ans<2e9) printf("%d\n",ans);
    else puts("-1");
}

 

posted on 2017-12-13 17:53  宣毅鸣  阅读(147)  评论(0编辑  收藏  举报