題目描述:
給定一棵有權無根樹,求一條路徑滿足路徑上邊權的最小值與路徑邊權之和的乘積盡量大,輸出最大乘積。1≤
n≤300000
1 ≤n
≤300000
解題思路:
思路肯定是將邊從大到小加入,這樣就是用找到經過這條邊的最長鏈了。
那如何找經過這條邊的最長鏈呢?
設這條邊連線的兩個聯通塊為s,
t s,t
,其塊內最長鏈分別是(a
1,a2
),(b
1,b2
) (a1
,a2)
,(b1
,b2)
,那經過該邊的最長鏈一定是(a
1,b1
),(a
1,b2
),(a
2,b1
),(a
2,b2
) (a1
,b1)
,(a1
,b2)
,(a2
,b1)
,(a2
,b2)
中的一條,而加入該邊後整個塊的最長鏈也一定是以上6條鏈中的一條,可以用反證法證明。
#include
#define ll long long
using
namespace
std;
int getint()
const
int n=300005;
int n,dep[n],fa[n][20];ll ans,dis[n];
int tot,first[n],nxt[n<<1],to[n<<1],w[n<<1];
struct edgebian[n];
inline
bool cmp(const edge &a,const edge &b)
struct nodebl[n];
int find(int x)
void add(int x,int y,int z)
void dfs(int u)
}int lca(int x,int y)
ll dis(int x,int y)
void merge(int x,int y,int w)
ans=max(ans,len*w);
if(cnt1==2&&(tmp=dis(a[1],a[2]))>len)s=a[1],t=a[2],len=tmp;
if(cnt2==2&&(tmp=dis(b[1],b[2]))>len)s=b[1],t=b[2],len=tmp;
bl[fy].id=fx,bl[fx].s=s,bl[fx].t=t;
}int main()
; for(int i=1;i1);sort(bian+1,bian+n,cmp);
for(int i=1;icout
0;}
BJ模擬 String(SAM LCT 主席樹)
傳送門 題意 給字串 s s 支援 1.末尾加入字元。2.查詢 l r role presentation l,r l r 中出現兩次的最長字串。題解 好題。考慮離線做法 動態插入後面的字元,更新前面 l l 的答案。當我們插入乙個字元 r role presentation r r的時候,與前面的...
旅遊規劃 樹的直徑
w市的交通規劃出現了重大問題,市 下決心在全市的各大交通路口安排交通疏導員來疏導密集的車流。但由於人員不足,w市市長決定只在最需要安排人員的路口安放人員。具體說來,w市的交通網路十分簡單,它包括n個交叉路口和n 1條街道,任意一條街道連線兩個交叉路口,並且任意兩個交叉路口之間都存在一條路徑互相連線。...
BJ模擬(2) D2T3 路徑規劃
路徑規劃 題目背景 thoj27 分析 這道題我打了乙個暴力,用樹鏈剖分實現不知道為什麼前兩個點都沒有過,但是別人完全不優化的暴力竟然都過了,這樣我很不服啊,不開心 qnq,本來呢,這道題敲乙個無腦的點分是可以卡卡常數過的,複雜度 o nlog2n 但是正如某學長所說,這樣非常的不優雅,那我們考慮一...