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

2021-08-08 03:33:09 字數 1484 閱讀 3411

time limit: 10 sec memory limit: 162 mb

submit: 738 solved: 203

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

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

輸出有p行,yes或no.

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

30%的資料,n≤100.

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

做完此題可看下poj 3237 tree

顯然一看就是點分治題,而且又是沒穿衣服的點分治題,完了完了全刷的是模板題,好頹廢,所以我們直接點分治就可以了,題目中問有沒有一條路徑為他所給的q次詢問的,分別輸出每次詢問的答案,我們先把詢問讀進來,然後每次在solve函式getdeep之後都用map來跑一遍,只要有當前的詢問值減去某個點的dis值,這個值在map裡面出現過,則說明是存在的

#include

#include

#include

#include

using

namespace

std;

const

int maxn=10000+100;

mapmp;

int sz[maxn],a[maxn],dis[maxn],vis[maxn],m,q[maxn],ans[maxn],root,sum,mx[maxn],n,head[maxn],tail;

struct lineline[maxn*2];

void add_line(int from,int to,int flow)

void getroot(int u,int fa)

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

if(mx[u]void getdeep(int u,int fa)

}void solve(int u)

for(register

int i=head[u];i;i=line[i].nxt)

}}int main()

mx[0]=0x7ffffff;root=0;sum=n;

for(register

int i=1;i<=m;i++)scanf("%d",&q[i]);

getroot(1,0);

solve(root);

for(register

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

return

0;}

BZOJ 1316 樹上的詢問 點分治

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

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分別...