BZOJ 2651 城市改建 樹形DP 模擬?

2022-08-03 12:51:21 字數 1368 閱讀 5446

給一顆樹,刪除一條邊再加一條邊,使它仍為一顆樹且任意兩點間的距離的最大值最小。

題目資料範圍描述有問題,n為1或重建不能使任意兩點距離最大值變小,可以輸出任意答案。

刪除一條邊後會使它變成兩顆樹,兩棵樹的直徑的中點相連一定是使距離最小的

紅色的邊為刪除重建的邊

在樹上dp維護每個子樹的最大直徑\(h[x]\),和去除這個子樹後的樹的最大直徑\(t[x]\),u為x的父親,刪除u-x這條邊並重建後的樹的最大直徑為

\[\max\+\frac+1,h[x],t[x]\}

\]設\(g[u]\)為以\(u\)為根的子樹中\(u\)能到達的最遠距離

設\(p[u]\)為去除以\(u\)為根的子樹後\(u\)能到達的最遠距離

自底向上

x為u的孩子,\(mx1\),\(mx2\)分別為\(g[x]\)的最大值和次大值

自頂向下

k為x的兄弟,\(mx1​\),\(mx2​\)分別為\(g[k]\)的最大值和次大值

然後bfs找重建的邊

實現細節很多,我寫的比較亂,建議自己根據dp式子模擬一下

#include#define fi first

#define se second

#define bug cout<

typedef pairpii;

pii e[maxn];

int g[maxn],h[maxn],p[maxn],t[maxn];

int ans=inf;

pii ans1,ans2;

void dfs1(int u,int fa)else if(g[x]>mx2)

h[u]=max(h[u],h[x]);

}h[u]=max(h[u],g[u]);

h[u]=max(mx1+mx2+2,h[u]);

}int pre[maxn],suf[maxn];

int pr[maxn],sf[maxn];

void dfs2(int u,int fa)

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

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

for(int i=1;imx1)else if(g[x]>mx2)

}mx1=mx2=-inf;

for(int i=len;i>=1;i--)else if(g[x]>mx2)

}for(int i=1;i<=len;i++)

dfs1(1,0);

dfs2(1,0);

work();

return 0;

}

2651 城市改建 樹形DP

我太sb了。一看輸出方案就瞎jb記錄了一坨資訊。最後發現根本沒有用。結果寫了6.7k。成功成為了bzoj寫的最長跑的最慢的選手2333。題目即在一棵樹上刪一邊加一邊,使得新樹的直徑最小。那麼我們就要維護直徑相關的資訊。於是大力dp。首先自底向上dp,設fi 表示以節點 i 為根的子樹的直徑,gi 表...

bzoj 3456 城市規劃

題意 求n個點的無向連通圖個數 n個點不同,答案對1004535809取模 n 130000 題解 生成函式的種種神奇應用 不過這玩意真是越來越不oi了 笑 這道題首先考慮遞推公式 設f x 為結點數為x的答案 那麼用總的無向圖數減去不連通的無向圖數目就是答案 f i 2 i i 1 2 f j 2...

bzoj3456 城市規劃

time limit 40 sec memory limit 256 mb submit 342 solved 204 submit status discuss 剛剛解決完電力網路的問題,阿狸又被領導的任務給難住了.剛才說過,阿狸的國家有n個城市,現在國家需要在某些城市對之間建立一些 路線,使得整...