bzoj 3669
Posted zhangleo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 3669相关的知识,希望对你有一定的参考价值。
思想基本同bzoj 2594,但是多了一步
首先我们发现这时的边有两个属性了,因此我们考虑先去掉其中一者的限制
我们把所有边按$a$大小排序,然后从小到大加入维护的最小生成树
每次加边时都按照$b$的大小操作bzoj 2594,然后更新答案即可
如果始终不联通输出-1
#include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <queue> #include <stack> #include <map> using namespace std; struct Ques int x,y,typ,num; q[1000005]; struct Edge int l,r,v1,v2; friend bool operator < (Edge a,Edge b) return a.v1==b.v1?a.v2<b.v2:a.v1<b.v1; edge[1000005]; map <pair<int,int>,int> M; int n,m,Q; int ch[2000005][2]; int vis[2000005]; int maxx[2000005]; int val[2000005]; int f[2000005]; int fl[2000005]; int ret[2000005]; void update(int x) maxx[x]=val[x]; if(edge[maxx[ch[x][0]]].v2>edge[maxx[x]].v2)maxx[x]=maxx[ch[x][0]]; if(edge[maxx[ch[x][1]]].v2>edge[maxx[x]].v2)maxx[x]=maxx[ch[x][1]]; bool be_root(int x) if(ch[f[x]][0]==x||ch[f[x]][1]==x)return 0; return 1; void pushdown(int x) if(fl[x]) swap(ch[ch[x][0]][0],ch[ch[x][0]][1]); swap(ch[ch[x][1]][0],ch[ch[x][1]][1]); fl[ch[x][0]]^=1,fl[ch[x][1]]^=1; fl[x]=0; void repush(int x) if(!be_root(x))repush(f[x]); pushdown(x); void rotate(int x) int y=f[x],z=f[y],k=(ch[y][1]==x); if(!be_root(y))ch[z][ch[z][1]==y]=x; f[x]=z; ch[y][k]=ch[x][!k],f[ch[x][!k]]=y; ch[x][!k]=y,f[y]=x; update(y),update(x); void splay(int x) repush(x); while(!be_root(x)&&x) int y=f[x],z=f[y]; if(!be_root(y)&&y) if((ch[y][1]==x)^(ch[z][1]==y))rotate(x); else rotate(y); rotate(x); update(x); void access(int x) int y=0; while(x) splay(x); ch[x][1]=y; update(x); y=x,x=f[x]; void makeroot(int x) access(x),splay(x); swap(ch[x][0],ch[x][1]),fl[x]^=1; void link(int x,int y) makeroot(x); f[x]=y; void split(int x,int y) makeroot(x),access(y),splay(y); void cut(int x,int y) split(x,y),ch[y][0]=f[x]=0,update(y); int findf(int x) access(x),splay(x),pushdown(x); while(ch[x][0])x=ch[x][0],pushdown(x); return x; inline int read() int f=1,x=0;char ch=getchar(); while(ch<‘0‘||ch>‘9‘)if(ch==‘-‘)f=-1;ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘;ch=getchar(); return x*f; int main() n=read(),m=read(); for(int i=1;i<=m;i++) edge[i].l=read(),edge[i].r=read(),edge[i].v1=read(),edge[i].v2=read(); if(edge[i].l>edge[i].r)swap(edge[i].l,edge[i].r); sort(edge+1,edge+m+1); int ans=0x3f3f3f3f; for(int i=1;i<=m;i++)val[i+n]=maxx[i+n]=i; for(int i=1;i<=m;i++) int f1=findf(edge[i].l),f2=findf(edge[i].r); if(f1==f2) split(edge[i].l,edge[i].r); if(edge[maxx[edge[i].r]].v2>edge[i].v2) int t=maxx[edge[i].r]; cut(edge[t].l,t+n),cut(edge[t].r,t+n); link(edge[i].l,i+n),link(edge[i].r,i+n); else link(edge[i].l,i+n),link(edge[i].r,i+n); int ff1=findf(1),ff2=findf(n); if(ff1==ff2) split(1,n); ans=min(ans,edge[i].v1+edge[maxx[n]].v2); if(ans==0x3f3f3f3f)printf("-1\\n"); else printf("%d\\n",ans); return 0;
以上是关于bzoj 3669的主要内容,如果未能解决你的问题,请参考以下文章