NOI2014 魔法森林 動態樹LCT

2021-09-10 16:42:20 字數 3146 閱讀 4259

為了得到書法大家的真傳,小e同學下定決心去拜訪住在魔法森林中的隱士。魔法森林可以被看成乙個包含個n

nn節點m

mm條邊的無向圖,節點標號為1⋯n

1\cdots n

1⋯n,邊標號為1⋯m

1\cdots m

1⋯m。初始時小e同學在號節點1

11,隱士則住在號節點n

nn。小e需要通過這一片魔法森林,才能夠拜訪到隱士。

魔法森林中居住了一些妖怪。每當有人經過一條邊的時候,這條邊上的妖怪就會對其發起攻擊。幸運的是,在號節點住著兩種守護精靈:a

aa型守護精靈與b

bb型守護精靈。小e可以借助它們的力量,達到自己的目的。

只要小e帶上足夠多的守護精靈,妖怪們就不會發起攻擊了。具體來說,無向圖中的每一條邊e

ie_i

ei​包含兩個權值a

ia_i

ai​與b

ib_i

bi​。若身上攜帶的a

aa型守護精靈個數不少於a

ia_i

ai​,且b

bb型守護精靈個數不少於b

ib_i

bi​,這條邊上的妖怪就不會對通過這條邊的人發起攻擊。當且僅當通過這片魔法森林的過程中沒有任意一條邊的妖怪向小e發起攻擊,他才能成功找到隱士。

由於攜帶守護精靈是一件非常麻煩的事,小e想要知道,要能夠成功拜訪到隱士,最少需要攜帶守護精靈的總個數。守護精靈的總個數為a

aa型守護精靈的個數與b

bb型守護精靈的個數之和。

輸入格式

第1行包含兩個整數n,m

n,mn,

m,表示無向圖共有n

nn個節點,m

mm條邊。 接下來m

mm行,第行包含4

44個正整數xi,

yi,a

i,bi

xi_,y_i,a_i,b_i

xi,​yi

​,ai

​,bi

​,描述第i

ii條無向邊。其中x

ix_i

xi​與y

iy_i

yi​為該邊兩個端點的標號,a

ia_i

ai​與b

ib_i

bi​的含義如題所述。 注意資料中可能包含重邊與自環。

輸出格式

輸出一行乙個整數:如果小e可以成功拜訪到隱士,輸出小e最少需要攜帶的守護精靈的總個數;如果無論如何小e都無法拜訪到隱士,輸出-1

如果沒有b

bb型守護精靈,那麼就是求1

11~n

nn的所有路徑中最大邊權的最小值。很容易想到用最小生成樹解決。現在一條邊有兩個權值,同樣按照kruskal演算法的思路,固定邊的一種權值a

ia_i

ai​,將其按從小到大排序,然後就可以發現,答案中b

ib_i

bi​就一定在以b

ib_i

bi​為權值的最小生成樹上,於是就可以用lct維護b

bb的最小生成樹。當1

11和n

nn連通時就更新答案。對於自環與重邊,可以不處理,lct會自動過濾。似乎還有一種用spfa的方法,供大家思考。 (lct也沒那麼長,壓行後百行都不到)

#include

#include

#include

using

namespace std;

const

int n=

500005

,m=100005

;const

int v=n+m,inf=int_max>>1;

typedef

long

long ll;

struct edge e[m]

;int n,m,fa[n]

,ans;

bool

cmp(edge a,edge b)

intgetf

(int x)

int c[v][2

],f[v]

;int mx[v]

,v[v]

,rv[v]

,st[v]

;void

init

(int x,

int p)

bool

nroot

(int x)

void

makerv

(int x)

void

pushup

(int x)

void

pushdown

(int x)

void

pushtg

(int x)

void

rotate

(int x)

void

splay

(int x)

void

access

(int x)

void

makert

(int x)

void

split

(int x,

int y)

void

link

(int x,

int y)

void

cut(

int x,

int y)

intmain()

;}sort

(e+1

,e+m+

1,cmp)

;for

(int i=

1;i<=n;i++

)init

(i,0

),fa[i]

=i;for

(int i=n+

1;i<=n+m;i++

)init

(i,i-n)

; ans=inf;

for(

int i=

1;i<=m;i++)}

if(getf(1

)==getf

(n))}if

(ans==inf)

printf

("-1");

else

printf

("%d"

,ans)

;return0;

}

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不...