BZOJ 1316 樹上的詢問 點分治

2021-08-02 20:11:50 字數 1555 閱讀 7726

time limit: 10 sec  memory limit: 162 mb

submit: 691  solved: 187

[submit][status][discuss]

一棵n個點的帶權有根樹,有p個詢問,每次詢問樹中是否存在一條長度為len的路徑,如果是,輸出yes否輸出no.

第一行兩個整數n, p分別表示點的個數和詢問的個數. 接下來n-1行每行三個數x, y, c,表示有一條樹邊x→y,長度為c. 接下來p行每行乙個數len,表示詢問樹中是否存在一條長度為len的路徑.

輸出有p行,yes或no.

6 41 2 5

1 3 7

1 4 1

3 5 2

3 6 3

1 8

13 14

yesyes

no yes

30%的資料,n≤100. 

100%的資料,n≤10000,p≤100,長度≤1000000. 

做完此題可看下poj 3237 tree

樹上路徑問題

考慮點分治

有q組詢問

那我們每組詢問都搞一遍就好了。。。

點分治中間搞會比搞q次快很多。。。

#include#include#include#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;

typedef long long ll;

inline int read()

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

return x*f;

}const int n=1000100;

const int m=10010;

const int q=111;

int n,m,ecnt,sum,last[m],dis[m],t[n],d[m],f[m],g[m],num[m],size[m],q[q],book[q],root;

bool vis[m];

struct edgee[m<<1];

inline void add(int u,int v,int val)

;last[u]=ecnt;}

void getroot(int u,int fa)

f[u]=max(f[u],sum-size[u]);

if(f[u]1&&g[j]*2==q[i])

book[i]+=opt*num[j]*(num[j]-1);

while(l0||!q[i])puts("yes");

else puts("no");

return 0;}/*

6 4

1 2 5

1 3 7

1 4 1

3 5 2

3 6 3

1 8

13 14

yes

yes

no yes

*/

BZOJ1316 樹上的詢問 點分治

一棵n個點的帶權有根樹,有p個詢問,每次詢問樹中是否存在一條長度為len的路徑,如果是,輸出yes否輸出no.第一行兩個整數n,p分別表示點的個數和詢問的個數 接下來n 1行每行三個數x,y,c,表示有一條樹邊x y,長度為c 接下來p行每行乙個數len,表示詢問樹中是否存在一條長度為len的路徑 ...

BZOJ1316 樹上的詢問 點分治

time limit 10 sec memory limit 162 mb submit 1017 solved 287 submit status discuss 一棵n個點的帶權有根樹,有p個詢問,每次詢問樹中是否存在一條長度為len的路徑,如果是,輸出yes否輸出no.第一行兩個整數n,p分別...

BZOJ 1316 樹上的詢問 點分治題解

time limit 10 sec memory limit 162 mb submit 738 solved 203 一棵n個點的帶權有根樹,有p個詢問,每次詢問樹中是否存在一條長度為len的路徑,如果是,輸出yes否輸出no.第一行兩個整數n,p分別表示點的個數和詢問的個數 接下來n 1行每行三...