[NOI2014T2] 마법 의 숲 - LCT 유지 보수 최소 생 성 트 리
#include
#include
#include
#include
#include
#define inf 1000000000
using namespace std;
int n,m,ans=inf;
int pre[150010]={0},ch[150010][2]={0},val[150010]={0},mx[150010]={0},mp[150010];
struct edge {int x,y,a,b;} e[100010];
bool rev[150010]={0},rt[150010];
bool cmp(edge a,edge b) {return a.avoid reverse(int x)
{
rev[x]^=1;
swap(ch[x][0],ch[x][1]);
}
void pushdown(int x)
{
if (rev[x])
{
rev[x]=0;
reverse(ch[x][0]);
reverse(ch[x][1]);
}
}
void pushup(int x)
{
if (val[x]>mx[ch[x][0]]&&val[x]>mx[ch[x][1]]) mx[x]=val[x],mp[x]=x;
else if (mx[ch[x][0]]>mx[ch[x][1]]) mx[x]=mx[ch[x][0]],mp[x]=mp[ch[x][0]];
else mx[x]=mx[ch[x][1]],mp[x]=mp[ch[x][1]];
}
void rotate(int x,bool f)
{
int y=pre[x];
ch[y][!f]=ch[x][f];
pre[ch[x][f]]=y;
ch[x][f]=y;
if (rt[y]) rt[y]=0,rt[x]=1;
else ch[pre[y]][ch[pre[y]][1]==y]=x;
pre[x]=pre[y];
pre[y]=x;
pushup(y),pushup(x);
}
void Push(int x)
{
if (!rt[x]) Push(pre[x]);
pushdown(x);
}
void Splay(int x)
{
Push(x);
while(!rt[x])
{
if (rt[pre[x]]) rotate(x,ch[pre[x]][0]==x);
else
{
int y=pre[x],z=pre[pre[x]];
bool f=(ch[z][1]==y);
if (ch[y][f]==x) rotate(y,!f),rotate(x,!f);
else rotate(x,f),rotate(x,!f);
}
}
pushup(x);
}
void access(int x)
{
int y=0;
do
{
Splay(x);
rt[ch[x][1]]=1,rt[ch[x][1]=y]=0;
pushup(x);
x=pre[y=x];
}while(x);
}
void move(int x)
{
access(x);
Splay(x);
reverse(x);
}
void link(int ed,int a,int b)
{
move(a);
move(b);
pre[a]=pre[b]=ed;
}
void cut(int ed,int a,int b)
{
move(ed);
access(ed);
Splay(a),Splay(b);
pre[a]=pre[b]=0;
}
int find_root(int x)
{
int now=x;
while(ch[now][0]) now=ch[now][0];
return now;
}
bool check(int x,int y)
{
int rx,ry;
access(x);Splay(x);rx=find_root(x);
access(y);Splay(y);ry=find_root(y);
return rx==ry;
}
void query(int x,int y,int &mxd,int &mxi)
{
move(x);
access(y);
Splay(y);
mxd=mx[y];
mxi=mp[y];
}
void work()
{
sort(e+1,e+m+1,cmp);
for(int i=1;i<=n+m;i++)
{
rt[i]=1;mx[i]=val[i]=0;mp[i]=i;
if (i>n) mx[i]=val[i]=e[i-n].b;
}
for(int i=1;i<=m;i++)
{
int mxd,mxi;
if (check(e[i].x,e[i].y))
{
query(e[i].x,e[i].y,mxd,mxi);
if (mxd>e[i].b)
{
cut(mxi,e[mxi-n].x,e[mxi-n].y);
link(n+i,e[i].x,e[i].y);
}
}
else link(n+i,e[i].x,e[i].y);
if (check(1,n))
{
query(1,n,mxd,mxi);
ans=min(ans,e[i].a+mxd);
}
if (e[i].a>ans) break;
}
}
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);
work();
if (ans==inf) printf("-1");
else printf("%d",ans);
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[NOI2014T2] 마법 의 숲 - LCT 유지 보수 최소 생 성 트 리원래 LCT 는 이렇게 사용 할 수 있 었 습 니 다............................................이 문제 의 표준 해법 은 LCT 로 최소 생 성 트 리 를 유지 하 는 것 이다.우...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.