NOI2014 魔法森林 LCT

2021-10-23 11:19:05 字數 1735 閱讀 8427

有n個點,m條邊,要使得從1點到n點的(最低要求ai和最低要求bi)的和最小,問最小和。

那麼,很顯然的,就是求乙個聯通關係,與最短路無關,因為限制條件不唯一,需要同時限制ai和bi,所以我們不妨列舉一維,然後再是維護一維。

我們對a關鍵字進行公升序處理,然後我們維護一棵b關鍵字的最小生成樹,然後列舉這樣的最小生成樹的答案不就可以了嗎?

我們不斷的進行加邊操作,然後對b關鍵字操作,每次看新的b能否替換之前的b樹,這就是我們維護的最小生成樹了,然後更新答案即可。

更新答案通過查詢現在的列舉到的a關鍵字的值,再加上此時1~n路徑上的最大的b關鍵字。

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define lowbit(x) ( x&(-x) )

#define pi 3.141592653589793

#define e 2.718281828459045

#define inf 0x3f3f3f3f

#define half (l + r)>>1

#define lsn rt<<1

#define rsn rt<<1|1

#define lson lsn, l, mid

#define rson rsn, mid+1, r

#define ql lson, ql, qr

#define qr rson, ql, qr

#define myself rt, l, r

using namespace std;

typedef unsigned long long ull;

typedef unsigned int uit;

typedef long long ll;

const int maxn = 15e4 + 7;

int n, m;

namespace lct

void pushup(int x)

void pushr(int x)

void pushdown(int x)

}void rotate(int x)

int stap[maxn];

void splay(int x)

}void access(int x)

}void makeroot(int x)

int findroot(int x)

splay(x);

return x;

}void split(int x, int y)

void link(int x, int y)

}void cut(int x, int y)

};using namespace lct;

struct edge

friend bool operator < (edge e1, edge e2)

} e[maxn];

int root[maxn];

int fid(int x)

int main()

else

}if(fid(1) == fid(n))

}if(ans == inf) printf("-1\n");

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

return 0;

}

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維護MST

bzoj3669 題面 從更簡單的情況入手,如果邊權只有 a 沒有 b應該怎麼處理?這時候問題就是找一條從1到n的路徑,使得最長的邊盡量短。根據最小生成樹的性質,這樣的邊一定在最小生成樹上。如果a 固定,得到的解法是一樣的。那麼可以分別討論每乙個 a,對於權值不大於 a 的邊對 b做一次最小生成樹。...