BZOJ3669: [Noi2014]魔法森林

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;
}


你可能感兴趣的:(BZOJ3669: [Noi2014]魔法森林)