JZOJ 4715 樹上路徑 (點分)

2021-08-08 00:22:35 字數 1568 閱讀 7503

description

給出一棵樹,求出最小的k,使得,且在樹中存在路徑p,使得k>=s且k<=e。(k為路徑p上的邊的權值和)

input

第一行給出n,s,e。n代表樹的點數,s,e如題目描述。

下面n-1行給出這棵樹的相鄰兩個節點的邊及其權值w。

output

輸出共一行乙個整數,表示答案。若無解輸出-1。

sample input

5 10 40

2 4 80

2 3 57

1 2 16

2 5 49

sample output

16 【樣例解釋】

1到2的路徑即為答案。

對於20%的資料滿足n<=300

對於50%的資料滿足n<=3000

對於60%的資料滿足n<=10^5

對於以上資料,滿足|e-s|<=50

對於100%的資料滿足n<=10^5,|e-s|<=10^6

對於所有資料滿足1<=wi<=1000,|e|,|s|<=10^9

思路:比較裸的點分,不過這道題維護的是最小值,就沒有可減的性質了,所以去重(路徑兩端在同一子樹內)就要直接判斷。

#include 

#include

#include

#include

#define ll long long

using

namespace

std;

const

int n = 100010;

int n, s, e, core, idc=0, sum;

int head[n], siz[n], mx[n], vis[n];

ll ans=2e17, dis[n];

struct edgeed[n<<2];

struct treea[n];

bool cmp(tree aa, tree bb)

void adde(int u, int v, ll w)

void getcore(int u, int f)

mx[u] = max(mx[u], sum-siz[u]);

if(mx[u] < mx[core]) core = u;

}void getdeep(int u, int f, int sroot)

a[++idc].tp = sroot;//屬於哪個子樹

a[idc].dis = dis[u];

}void count()

else

}}void solve(int u, int f)

}int main()

core = 0; mx[core] = 0x3fffffff; sum = n;

getcore(1, 0); solve(core, 0);

if( ans > e ) cout

<< -1

<< endl;//

else

cout

<< ans << endl;

return

0;}

JZOJ4715樹上路徑 點分治

這居然是聯賽題我一臉懵逼。根本沒往那方向上想。題目大意 讓你求樹上最短的路徑,但是路徑長度必須 l,r,n 10 5,r l 10 6,l,r 10 9 其實是我點分治沒怎麼打過,這其實是一道很一眼的點分治的題。我是懵比了。可以算是模板題吧,我是直接點分治莽一波,然後就過了,題解還說是二分,我比賽時...

JZOJ5055 樹上路徑

給定一棵 n 個節點的無根樹,每個點都有乙個非負整數的權值va li,定義一條路徑的價值為路徑上的點權和減去路徑的點權最大值。給定引數 p 請求出樹上有多少條價值是 p的倍數的路徑。注意 單點也算路徑。並且路徑 u v 和 v u 只算一次。1 n 105 1 p 107,0 va li 10 9 ...

JZOJ7月16日提高組T3 樹上路徑

題解現在有一棵n個點的無向樹,每個點的編號在1 n之間,求出每個點所在的最長路。輸入檔名為tree.in。第一行為乙個整數n。之後n 1行,每行三個整數u,v,w,分別表示一條邊連的兩個點和邊權。輸出檔案tree.out,共n行,分別表示經過每個點的最長路。41 2 3 1 3 4 1 4 277 ...