NOI2014 魔法森林 LCT維護MST

2021-08-11 15:37:37 字數 1446 閱讀 6083

bzoj3669 題面

從更簡單的情況入手,如果邊權只有

a 沒有

b應該怎麼處理?這時候問題就是找一條從1到n的路徑,使得最長的邊盡量短。根據最小生成樹的性質,這樣的邊一定在最小生成樹上。如果a

固定,得到的解法是一樣的。那麼可以分別討論每乙個

a,對於權值不大於

a 的邊對

b做一次最小生成樹。暴力做會超時。考慮到隨著

a 的變大,可用的邊也逐漸增多,那麼只要在加邊的同時更新最小生成樹就可以了。這個操作可以用lct處理。

#include

#include

#define maxn 150005

#define maxm 200005

using

namespace

std;

int n,m,ans=1e9;

struct nodeedge[maxm];

bool

operator

<(node x,node y)

void update(int p)

void zig(int x)

fa[x]=z;fa[y]=x;fa[rs[x]]=y;

ls[y]=rs[x];rs[x]=y;

update(y);update(x);

}void zag(int x)

fa[x]=z;fa[y]=x;fa[ls[x]]=y;

rs[y]=ls[x];ls[x]=y;

update(y);update(x);

}int s[maxn],top;

void splay(int x)

else

else}}

}void access(int x)

}void setrt(int x)

void link(int x,int y)

void cut(int x,int y)

int findrt(int x)

int tot,lk[maxm][2];

void add(int x,int y,int v)

void del(int x)

int getmax(int x,int y,int op)

int main()

x=findrt(edge[j].st);

y=findrt(edge[j].en);

if(x!=y)add(edge[j].st,edge[j].en,edge[j].vb);

else

}j++;

}if(findrt(1)!=findrt(n))continue;

ans=min(ans,i+getmax(1,n,1));

}if(ans==1e9)puts("-1");

else

printf("%d\n",ans);

}

NOI2014 魔法森林 LCT

為了 得到書法大家的真傳,小e同學 下定決心去 拜訪住在 魔法森林中的 隱士。魔法森林 可以被看成乙個 包含個n節點m條邊的無向圖 節點標號為1.n 邊標號為1.m 初始時 小e同學在 號節點1 隱士則 住在號節點n 小e需要通過這一片魔法森林,才能夠拜訪到隱士。魔法森林 中居住了 一些妖怪。每當有...

NOI2014魔法森林 LCT

題目 為了得到書法大家的真傳,小e同學下定決心去拜訪住在魔法森林中的隱士。魔法森林可以被看成乙個包含個n節點m條邊的無向圖,節點標號為 1 n1 n,邊標號為1 m1 m。初始時小e同學在 11 號節點,隱士則住在 nn 號節點。小e需要通過這一片魔法森林,才能夠拜訪到隱士。魔法森林中居住了一些妖怪...

NOI2014 魔法森林 LCT

有n個點,m條邊,要使得從1點到n點的 最低要求ai和最低要求bi 的和最小,問最小和。那麼,很顯然的,就是求乙個聯通關係,與最短路無關,因為限制條件不唯一,需要同時限制ai和bi,所以我們不妨列舉一維,然後再是維護一維。我們對a關鍵字進行公升序處理,然後我們維護一棵b關鍵字的最小生成樹,然後列舉這...