bzoj 3669 魔法森林

2021-08-01 07:40:20 字數 3302 閱讀 2852

time limit: 30 sec  

memory limit: 512 mb

submit: 2690  

solved: 1667 [

submit][

status][

discuss]

為了得到書法大家的真傳,

小e同學

下定決心去

拜訪住在

魔法森林中的

隱士。魔法森林

可以被看成乙個

包含個n節點m條邊的無向圖

,節點標號為1..n

,邊標號為1..m

。初始時

小e同學在

號節點1

,隱士則

住在號節點n

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

魔法森林

中居住了

一些妖怪。每當有人

經過一條邊

的時候,這

條邊上的妖怪就會

對其發起

攻擊。幸運

的是,在號

節點住著兩種守護精靈

:a型守護精靈與b型守護精靈

。小e可以借助

它們的力量

,達到自己的目的。只要

小e帶上足夠多的守護精靈,

妖怪們就不會發起攻擊

了。具體來說

,無向圖中的

每一條邊

ei包含

兩個權值ai

與bi。若身上

攜帶的a

型守護精靈

個數不少於ai

,且b型守護精靈個數

不少於bi

,這條邊上的妖怪

就不會對

通過這條邊

的人發起攻擊

當且僅當

通過

魔法森林

的過程中沒有

任意一條邊

妖怪

小e發起攻擊

他才能成功

找到

隱士。

由於攜帶守護精靈是一件非常

麻煩的事,小e想要知道,

要能夠成功拜訪到隱士,最少

需要攜帶守護精靈

的總個數

守護精靈

總個數

為a型守護精靈的個數與b型守護精靈的個數之和。

第1行包含兩個整數n,m,表示無向圖共有n個節點,m條邊。 接下來m行,第行包含4個正整數xi,yi,ai,bi,描述第i條無向邊。其中xi與yi為該邊兩個端點的標號,ai與bi的含義如題所述。 注意資料中可能包含重邊與自環。

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

【輸入樣例1】

4 51 2 19 1

2 3 8 12

2 4 12 15

1 3 17 8

3 4 1 17

【輸入樣例2】

3 11 2 1 1

【輸出樣例1】

32【樣例說明1】

如果小e走路徑1→2→4,需要攜帶19+15=34個守護精靈;

如果小e走路徑1→3→4,需要攜帶17+17=34個守護精靈;

如果小e走路徑1→2→3→4,需要攜帶19+17=36個守護精靈;

如果小e走路徑1→3→2→4,需要攜帶17+15=32個守護精靈。

綜上所述,小e最少需要攜帶32個守護精靈。

【輸出樣例2】

-1【樣例說明2】

小e無法從1號節點到達3號節點,故輸出-1。

2<=n<=50,000

0<=m<=100,000

1<=ai ,bi<=50,000

【分析】

wc 水管 的水化水化版...

【**】

//noi 2014 膜法森林

#include#include#include#include#define ll long long

#define fo(i,j,k) for(i=j;i<=k;i++)

using namespace std;

const int mxn=200005;

int n,m,top,ans=1e9+7;

struct edge e[mxn];

int f[mxn],ch[mxn][2],rev[mxn],st[mxn],mx[mxn],val[mxn];

inline bool comp(edge x,edge y)

inline void reverse(int x)

inline void pushdown(int x)

inline void rotate(int x)

inline void splay(int x)

inline void access(int x)

inline void makeroot(int x)

inline int find(int x)

inline void split(int x,int y)

inline void link(int x,int y)

inline void cut(int x,int y)

int main()

{ int i,j;

scanf("%d%d",&n,&m);

fo(i,1,m) scanf("%d%d%d%d",&e[i].l,&e[i].r,&e[i].a,&e[i].b);

sort(e+1,e+m+1,comp);

fo(i,1,m)

{ val[i+n]=e[i].b;

int u=e[i].l,v=e[i].r;

if(find(u)!=find(v))

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

else

{ split(u,v);

int tmp=mx[v]; //u->v路徑最大權節點

if(val[i+n]

刷題總結 魔法森林(bzoj3669)

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

bzoj3669 魔法森林 LCT 並查集

ac通道 題解 據說spfa可以說過。lct做法 將邊權按其中乙個值排序,往裡面加邊,用並查集維護圖的連通性,當1與n聯通時更新答案。用lct維護圖中的另一邊權的最大值,如果邊的兩端不連通直接加入,否則說明構成了環,刪去環上最大的邊。小技巧 邊可以建成點,向邊的兩端連邊,在該點上維護權值資訊。ps ...

bzoj3669 NOI2014 魔法森林

給定n個點m條邊的無向圖,每條邊有兩個權值a與b。求一條1到n的路徑使得路徑經過邊的最大a與最大b的和最小。無法到達輸出 1。n 50000,m 100000。我們嘗試列舉路徑的最大a值,那麼我們只需按照a排序按順序插入,維護1到n的b最大值即可。用並查集維護連通性。當加入j到k這條邊時如果形成環,...