LCT
一开始自己脑子抽用节点的权值表示连向父亲的边的长度
后来发现不能拿来搞翻转
然后看了别人的题解 发现居然可以新开一个点。。。。
药丸
之后又调试了一天 最后听了度教的话 重打。。
发现好像是自己的Access打跪了。。。。
完了。。。。一天只调好一道题。。。。
去死吧 !
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> using namespace std; char c; inline void read(int &a) {a=0;do c=getchar();while(c!=EOF&&(c<'0'||c>'9'));if(c==EOF)exit(0);while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();} struct Node { Node *lc,*rc,*f; int rev; int b,c; Node *Maxb; inline bool Heavy(){return f->lc==this||f->rc==this;} inline bool l(){return f->lc==this;} }*empty; Node E[170001]; inline void begin(){empty=new Node;empty->lc=empty->rc=empty;empty->b=0;empty->Maxb=empty;} inline void pushdown(Node *a) {Node *tp=a->lc;a->lc=a->rc;a->rc=tp;a->lc->rev^=1,a->rc->rev^=1,a->rev^=1;} inline void updata(Node *a) {a->Maxb=a->rc->Maxb->b> a->lc->Maxb->b?a->rc->Maxb:a->lc->Maxb;if(a->b>a->Maxb->b)a->Maxb=a;} inline void Lc(Node *a) { Node *newf; if(a->f->Heavy()) if(a->f->l()) newf=a->f->f,a->f->f->lc=a; else newf=a->f->f,a->f->f->rc=a; else if(a->f->f==a->f) newf=a; else newf=a->f->f; a->rc->f=a->f; a->f->lc=a->rc; a->rc=a->f; a->f->f=a; a->f=newf; updata(a->rc); updata(a); } inline void Rc(Node *a) { Node *newf; if(a->f->Heavy()) if(a->f->l()) newf=a->f->f,a->f->f->lc=a; else newf=a->f->f,a->f->f->rc=a; else if(a->f->f==a->f) newf=a; else newf=a->f->f; a->lc->f=a->f; a->f->rc=a->lc; a->lc=a->f; a->f->f=a; a->f=newf; updata(a->lc); updata(a); } inline void Turn(Node *a) {a->l()?Lc(a):Rc(a);} inline void Change(Node *a) { if(a->f->rev)pushdown(a->f); if(a->rev)pushdown(a); Turn(a); } inline void Twice_Change(Node *a) { if(a->f->f->rev)pushdown(a->f->f); if(a->f->rev)pushdown(a->f); if(a->rev)pushdown(a); a->l()==a->f->l()?Turn(a->f):Turn(a);Turn(a); } inline void Splay(Node *a) { while(a->Heavy()&&a->f->Heavy()) Twice_Change(a); while(a->Heavy())Change(a); } inline void Access(Node *a) { if(a->f==a)return; if(a->rev)pushdown(a); while(true) { Splay(a); if(a->f==a)return; Splay(a->f); if(a->f->rev)pushdown(a->f); a->f->rc=a; updata(a->f); } } inline void MakeRoot(Node *a) { Access(a); a->lc->rev^=1; a->lc=empty; } inline Node *Split(Node *a,Node *b) { MakeRoot(a); Access(b); while(b->lc!=a) Change(a); return a->rc; } inline void Cut(Node *a,Node *b) { Split(a,b); b->lc=empty; a->f=a; } inline void Link(Node *a,Node *b) { MakeRoot(a); a->f=b; Access(a); } int f[200001],size[200001]; int find(int x){return f[x]=(f[x]==x?x:find(f[x]));} inline int Union(int x,int y){if(size[find(x)]>=size[find(y)])f[f[x]]=f[y],size[f[y]]+=size[f[x]];else f[f[y]]=f[x],size[f[x]]+=size[f[y]];} struct Side { int u,v,a,b; inline friend bool operator <(Side a,Side b){return a.a<b.a;} }Line[100001]; int main() { int i,j,k,n,m; read(n); read(m); begin(); for(i=1;i<=n+m;i++) size[i]=1,f[i]=i,E[i].f=&E[i],E[i].lc=E[i].rc=empty,E[i].Maxb=&E[i],E[i].b=0; for(i=1;i<=m;i++) read(Line[i].u), read(Line[i].v), read(Line[i].a), read(Line[i].b); sort(Line+1,Line+1+m); int pos=1,maxa,ans=1<<29; for(i=1;i<=m;i++) { maxa=Line[i].a; if(Line[i].v^Line[i].u) if(find(Line[i].u)^find(Line[i].v)) { Union(Line[i].u,Line[i].v); E[i+n].b=Line[i].b; E[i+n].c=i; Link(&E[Line[i].u],&E[i+n]); Link(&E[i+n],&E[Line[i].v]); } else { Node *tp=Split(&E[Line[i].u],&E[Line[i].v])->Maxb; if(tp->b>Line[i].b) { Cut(tp,&E[Line[tp->c].u]); Cut(tp,&E[Line[tp->c].v]); E[i+n].b=Line[i].b; E[i+n].c=i; Link(&E[Line[i].u],&E[i+n]); Link(&E[i+n],&E[Line[i].v]); } } if(find(1)==find(n)) { Node *tp=Split(&E[1],&E[n]); ans=min(ans,maxa+tp->Maxb->b); } } printf("%d\n",ans==1<<29?-1:ans); return 0; return 0; }