Luogu2680 運輸計畫

2022-05-17 14:47:02 字數 2690 閱讀 6455

我們對每條邊\(i\)單獨考慮,那麼設\(v_i\)為這條邊的長度,經過它的路徑長度集合為\(s\),未經過它的路徑長度集合為\(t\)

\[ans_i=\max

\begin

s_-v_i \\

t_\end \\

ans=\min ans_i

\]對於\(s_\),我們直接對於一條長度為\(l\)的路徑,該路徑上的邊都對\(l\)取\(\max\),用樹鏈剖分很容易處理

對於\(t_\),對於一條長度為\(l\)的路徑,不在該路徑上的邊都對\(l\)取\(\max\),也就是計算\(s_\)時邊的補集,我們可以記錄樹剖時覆蓋了哪些段,剩餘的段就是\(t_\)應當覆蓋的了,由於樹剖頂多\(\log n\)段,\(t_\)覆蓋的段頂多比\(s_\)覆蓋的段多乙個

計算路徑長度\(l\),用了帶按秩合併優化的\(tarjan\)求\(lca\)

時間複雜度:\(o(n \log^2 n)\)

掛點\(1.\)線段樹忘開四倍空間。。。

掛點\(2.\)一開始\(t\)了,結果發現是它的鍋

#define rmin(x,y) ((xy)?x:y)
在下面的**的線段樹中,由於\(define\),需要先線段樹搜尋一次,與\(y\)比較,然後返回值時再搜尋一次,時間**

經驗:下次寫什麼函式之類的再也不用\(define\)了\(qaq\)

錯誤**:

#define rmin(x,y) ((xy)?x:y)

#define ls (p << 1)

#define rs ((p << 1) | 1)

#define lc ls,l,mid

#define rc rs,mid+1,r

struct segment_tree

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

if (y<=mid)

modify(lc,x,y,z); else

if (x>mid)

modify(rc,x,y,z); else

}int query(int p,int l,int r,int x)

}t1,t2;

完整\(ac\)**

\(code:\)

#include#include#include#include#define n 300005

using namespace std;

int n,m,x,y,z,tot=0,fr[n],nxt[n << 1],d1[n << 1],d2[n << 1];

int cnt=0,f[n],dep[n],son[n],sz[n],dfn[n],t[n],len[n];

int ans,ft[n],rf[n],rz[n],rg[n],lca[n];

struct node

bool operator < (const node &b) const

return s;

}void write(int x)

void add(int x,int y,int z)

int getf(int x)

void dfs1(int u)

int fu=getf(u);

int fv=getf(v);

if (rz[fv]<=rz[fu])

else

}for (vector:: iterator it=e[u].begin();it!=e[u].end();++it)

if (rf[it->x])

lca[it->y]=rg[getf(it->x)];

}void dfs2(int u,int tt)

}#define ls (p << 1)

#define rs ((p << 1) | 1)

#define lc ls,l,mid

#define rc rs,mid+1,r

struct segment_tree

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

if (y<=mid)

modify(lc,x,y,z); else

if (x>mid)

modify(rc,x,y,z); else

}int query(int p,int l,int r,int x)

}t1,t2;

void achange(int x,int y,int z)

sort(g+1,g+g0+1);

int o=1;

for (int i=1;i<=g0;o=g[i].y+1,i++)

if (o<=n)

t2.modify(1,1,n,o,n,z);

}int main()

for (int i=1;i<=m;i++)

q[i].x=read(),q[i].y=read(),e[q[i].x].push_back(node(q[i].y,i)),e[q[i].y].push_back(node(q[i].x,i));

dfs1(1);

dfs2(1,1);

for (int i=1;i<=m;i++)

ans=1000000007;

for (int i=2;i<=n;i++)

write(ans),putchar('\n');

return 0;

}

luogu2680 運輸計畫

很明顯,由於是求最長路的最小值,我們可以使用二分求解.我們二分乙個長度 mid 將所有使得 dis u,v 大於 mid 的點對 u,v 找出,設總共有 m 條這樣的邊,那麼我們需要改變的改變邊一定是被這 m 條邊都經過的邊,所以我們只需要找到滿足這個要求的長度最大的改變邊使得這 m 條邊中最長的一...

luogu2680 運輸計畫

首先二分列舉答案t,考慮刪去的邊應滿足的條件 所有大於 t的鏈全部經過且長度不小於最長鏈 t,第二個條件很好判斷,考慮第乙個條件。先考慮有祖先 後代關係的鏈,用如果把這條鏈到 1看成乙個序列,那麼差分一下再 dfs一遍就可以對這條鏈上每乙個點打上標記。然後沒有祖先 後代關係的鏈,同樣可以分解成兩條鏈...

題解 LuoGu2680 運輸計畫

原題傳送門 去年覺得是道難題,現在覺得這著實是道大水題 題意 一棵樹,給出幾條路徑 從點x到點y 可以使一條邊長度變為0,使得路徑長度最大值最小 思路 就搞定了 接著想如何實現 總結 noip的題目還是很可以的,演算法 思維難度不高,應用性還是比較強的 用到了許多小演算法 lca,二分,樹上差分 c...