按a从小到大排序,然后按b建图。
每次只需要找1~n中最大的b加当前的a计算答案即可。
这里还有一个小操作就是化边为点,把一条边的边权看做一个点的点权然后多连两条边。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=4e5+10; 4 int f[N],fa[N],ma[N],pos[N],c[N][2],rev[N],s[N],n,m,ans=2e9,w[N]; 5 struct node{ 6 int x,y,a,b; 7 bool operator <(const node &b)const{ 8 return a<b.a; 9 } 10 }a[N]; 11 bool isroot(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;} 12 inline int get(int x){return x==f[x]?x:f[x]=get(f[x]);} 13 void pushup(int x) 14 { 15 if(rev[x]) 16 { 17 rev[x]^=1;rev[c[x][0]]^=1;rev[c[x][1]]^=1; 18 swap(c[x][0],c[x][1]); 19 } 20 return; 21 } 22 void update(int x) 23 { 24 ma[x]=w[x];pos[x]=x; 25 if(ma[c[x][0]]>ma[x])ma[x]=ma[c[x][0]],pos[x]=pos[c[x][0]]; 26 if(ma[c[x][1]]>ma[x])ma[x]=ma[c[x][1]],pos[x]=pos[c[x][1]]; 27 return; 28 } 29 void rotate(int x) 30 { 31 int y=fa[x],z=fa[y],l,r; 32 l=c[y][1]==x;r=l^1; 33 if(!isroot(y))c[z][c[z][1]==y]=x; 34 fa[x]=z;fa[y]=x;fa[c[x][r]]=y; 35 c[y][l]=c[x][r];c[x][r]=y; 36 update(y);update(x); 37 } 38 void splay(int x) 39 { 40 int top=0,i; 41 for(i=x;!isroot(i);i=fa[i])s[++top]=i;s[++top]=i; 42 for(;top;top--)pushup(s[top]); 43 while(!isroot(x)) 44 { 45 int y=fa[x],z=fa[y]; 46 if(!isroot(y)) 47 { 48 if(c[y][0]==x^c[z][0]==y)rotate(x); 49 else rotate(y); 50 } 51 rotate(x); 52 } 53 return; 54 } 55 void access(int x) 56 { 57 int y=0; 58 while(x) 59 { 60 splay(x); 61 c[x][1]=y; 62 y=x;x=fa[x]; 63 } 64 } 65 void mroot(int x) 66 { 67 access(x);splay(x);rev[x]^=1; 68 } 69 void link(int x,int y) 70 { 71 mroot(x);fa[x]=y;splay(x); 72 } 73 void cut(int x,int y) 74 { 75 mroot(x);access(y);splay(y);c[y][0]=fa[x]=0; 76 } 77 int main() 78 { 79 scanf("%d%d",&n,&m); 80 for(int i=1;i<=n+m;++i)f[i]=i; 81 for(int i=1;i<=m;++i) 82 { 83 scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].a,&a[i].b); 84 } 85 sort(a+1,a+1+m); 86 for(int i=1;i<=m;++i) 87 { 88 w[i+n]=a[i].b; 89 } 90 for(int i=1;i<=m;++i) 91 { 92 if(a[i].x==a[i].y)continue; 93 int fx=get(a[i].x),fy=get(a[i].y); 94 if(fx!=fy) 95 { 96 link(a[i].x,i+n);link(i+n,a[i].y); 97 f[fx]=fy; 98 } 99 else 100 { 101 mroot(a[i].x);access(a[i].y); 102 splay(a[i].y);int tmp=pos[c[a[i].y][0]]; 103 if(w[tmp]>a[i].b) 104 { 105 cut(tmp,a[tmp-n].x);cut(tmp,a[tmp-n].y); 106 link(a[i].x,n+i);link(a[i].y,n+i); 107 } 108 } 109 if(get(1)==get(n)) 110 { 111 mroot(1); 112 access(n); 113 splay(n); 114 ans=min(ans,a[i].a+ma[c[n][0]]); 115 } 116 } 117 if(ans!=2e9) 118 printf("%d\n",ans); 119 else puts("-1"); 120 return 0; 121 }