NOI 2014 魔法森林

2022-05-31 08:48:11 字數 1163 閱讀 2323

乙個有\(n\)個點,\(m\)條邊的無向圖,每條邊都另有兩個權值\(a_i\)和\(b_i\),一開始有兩個指數,\(a\),\(b\),如果你的\(a>=a_i,b>=b_i\)那麼你就可以通過這條邊,求\(a+b\)的最小值。

\(lct\)裸題。

注意到有兩個指數,那我們肯定要先通過各種方法搞掉乙個指數,再去維護另乙個指數,比如用\(cdq\)分治,當然這題只要用個\(sort\),再維護一棵最小生成樹,即可。

把邊按\(a_i\)排序,然後一條一條地加入\(lct\),如果目前這條邊的兩端以在同一連通塊中,那麼加入這條邊之後肯定就會變成乙個環,那麼如果原連通塊中\(b_i\)最大的一條邊比該邊的\(b_i\)小,那麼就把最大的那條邊刪了,讓該邊加入即可。

乙個邊權轉點權的無腦方法:

#includeusing namespace std;

const int n=200005,inf=1e6+7;

int w[n],val[n],fa[n],rev[n],ch[n][2],max[n],p[n];

int n,m,opt,x,y,ans,t;

struct edge e[n];

bool cmp(edge a,edge b)

void pushdown(int x)

}void allpushdown(int x)

void rotate(int x)

void splay(int x)

void access(int x)

void makert(int x)

void link(int x,int y)

void cut(int x,int y)

int query(int x,int y)

int main()

else

} else p[find(u)]=find(v);

val[i+n]=e[i].b,max[i+n]=i+n;

link(u,i+n),link(i+n,v);

if (find(1)==find(n)) ans=min(ans,e[i].a+val[query(1,n)]);

} if (ans==inf) puts("-1"); else printf("%d\n",ans);

return 0;

}

NOI2014 魔法森林

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

NOI2014 魔法森林

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

NOI2014 魔法森林

noi2014 魔法森林 要求a 與 b 的總和最小 可以按a排序 再以b為權值維護一顆樹 lct維護最小生成樹 要解決的問題 將每一條邊變為乙個點 邊權變為點權 舉個栗子 u v有一條邊權為w的邊 怎lct連邊方式為 u new v new的點權為w 不斷維護最小生成樹 如果新加入的邊的 u與v不...