BZOJ 1758 Wc2010 重建計畫

2022-09-11 02:12:13 字數 2320 閱讀 7773

bzoj 1758

參考部落格

給出乙個 \(n\) 個節點帶邊權的樹,要求找出一條邊數在 \([l,u]\) 之間的路徑使得 \(\dfrace(w)}\) 最大

\(n\le100000,1\le l\le u\le n-1,v_i\le1000000\)

40sec,128mb

首先01分數規劃轉判斷問題,現在我們每個邊有新的邊權,我們要求樹上邊權最大的一條邊數 \([l,u]\) 的路徑

因為與深度有關,可以使用長鏈剖分解決,現在要用線段樹維護乙個區間最值,那麼之前的指標實現移位就無法使用了,考慮陣列只會向右移位**移方程為 \(f(v,j)->f(u,j+1)\)),那麼可以採用另一種移位方法,將樹剖分成鏈,那麼\(f(u,j)\) 的值就儲存在 \(val(dfn[u]+j)\) 位置,對 \(val\) 陣列維護乙個線段樹就好了

#include #include #include using namespace std;

inline char nc()

templatevoid read(t & x)

while(ch>='0'&&ch<='9')

x *= f;

}#define lson u << 1, l, mid

#define rson u << 1 | 1, mid + 1, r

const double eps = 1e-5;

const double infty = 1e18;

const int maxn = 100000 + 5;

const int maxe = maxn * 2;

const int maxv = 1000000 + 5;

int n, l, u; double an;

int head[maxn], ecnt;

double mid;

int dfn[maxn], len[maxn], son[maxn], cost[maxn], dfc;

double r[maxn];

struct edge

} g[maxe];

struct segment_tree

void build(int u, int l, int r)

int mid = (l + r) >> 1;

build(lson), build(rson);

pushup(u);

} void update(int u, int l, int r, int qp, double qv)

int mid = (l + r) >> 1;

if(qp <= mid) update(lson, qp, qv);

else update(rson, qp, qv);

pushup(u);

} double query(int u, int l, int r, int ql, int qr)

int mid = (l + r) >> 1;

if(qr <= mid) return query(lson, ql, qr);

else if (ql > mid) return query(rson, ql, qr);

else

}} seg;

inline void addedge(int u, int v, int w)

void dfs1(int u, int fa) }}

void dfs2(int u, int fa)

for(int i = head[u]; ~ i; i = g[i].nex)

} double query(int u, int l, int r)

void dp(int u, int fa, double dis)

seg.update(1, 1, n, dfn[u], dis);

for(int i = head[u]; ~ i; i = g[i].nex)

for(int j = 0; j <= len[v]; ++j)

} an = max(an, query(u, l, u) - dis);

}bool judge()

double solve()

return l;

}int main()

dfs1(1, 0), dfs2(1, 0);

printf("%.3lf\n", solve());

return 0;

}

BZOJ1758 WC2010 重建計畫

description input 第一行包含乙個正整數n,表示x國的城市個數.第二行包含兩個正整數l和u,表示政策要求的第一期重建方案中修建道路數的上下限 接下來的n 1行描述重建小組的原有方案,每行三個正整數 a i,b i,v i 分別表示道路 a i,b i 其價值為 v i 其中城市由1....

BZOJ 1758 Wc2010 重建計畫

要求平均值最大,二分平均值,判定是否存在一條合法路徑權值為正數,點分治 單調佇列 看上去沒有任何問題,然而其實每次點分的時候要按子樹深度從小到大排序然後更新答案 複雜度o n log 2 n 這個東西交上去又t了,然後學習了一下分數規劃怎麼二分,發現了一點神奇的方法,交上去又t了 可能我自己寫炸了 ...

WC2010 重建計畫

嘟嘟嘟 要不這篇部落格我水一下?思路很顯然,點分治 01分數規劃 單調佇列。但就是難寫。點分治的時候我們把每乙個點到重心這條鏈按深度排序,然後對於每乙個點的鏈就有乙個連續深度的區間可以和這條鏈拼上,因為要找一條權值大於 0 的鏈,那就相當於找這個區間的最大值。然後隨著點深度遞增,這個區間就不斷向左移...