給定一棵有n個點的樹,有m個詢問,每個詢問樹上距離為k的點對是否存在。樹的權值最多不超過c。n<=10000,m<=100,c<=1000,k<=10000000。關於樹的路徑的問題,點分治是一種最吼的工具。由於這道題的m比較小,列舉k,通過set儲存每顆子樹中點的路徑值,在set中查詢每個k值是否成立即可。似乎空間消耗很小,只用了2.3mb。
#include #include #include #include using namespace std;
const int maxn=1e4+5;
struct graph
}edge[maxn*2];
int cnte, fir[maxn];
void addedge(int x, int y, int v)
edge& getlink(int x)
void reset()
}g;int n, m, k[maxn], size[maxn], f[maxn];
int dep[maxn], tail;
sets;
bool done[maxn], hasans[maxn];
//獲取子樹大小和最大子樹大小
void predfs(int now, int par, int num)
f[now]=max(f[now], num-size[now]);
}//找到根
int getroot(int now, int par)
return core;
}//獲取到所有點的深度
void getdep(int now, int par, int step)
void solve(int now, int par, int num)
//不能統計帶有回頭路的
e=g.getlink(now);
done[now]=true;
for (; e.to; ++e) if (e.to!=par&&!done[e.to])
solve(e.to, now, size[e.to]); //找子樹
}void get(int &x)
int main()
for (int i=1; i<=m; ++i) get(k[i]);
solve(1, 0, n);
for (int i=1; i<=m; ++i) puts(hasans[i]?"aye":"nay");
return 0;
}
Luogu3806 點分治(點分治)
給定一棵有n個點的樹 詢問樹上距離為k的點對是否存在。n,m 接下來n 1條邊a,b,c描述a到b有一條長度為c的路徑 接下來m行每行詢問乙個k 對於每個k每行輸出乙個答案,存在輸出 aye 否則輸出 nay 不包含引號 點分治的模板題目,不做過多的解釋 據我這個蒟蒻的觀察 這道題的複雜度是o n2...
Luogu3806 點分治(點分治)
給定一棵有n個點的樹 詢問樹上距離為k的點對是否存在。n,m 接下來n 1條邊a,b,c描述a到b有一條長度為c的路徑 接下來m行每行詢問乙個k 對於每個k每行輸出乙個答案,存在輸出 aye 否則輸出 nay 不包含引號 點分治的模板題目,不做過多的解釋 據我這個蒟蒻的觀察 這道題的複雜度是 o n...
Luogu P3806點分治模板(點分治)
題目鏈結 wc聽不懂lca講的高等數學專場 乙個字都聽不懂 然後就自學了點分治。點分治就是我先處理完跟根有關的東西,然後把根標記掉,把原樹拆成若干個聯通塊,然後分別對每個聯通塊 每個小樹 搞一模一樣的操作。然後要每次求重心,因為點分治複雜度跟遞迴深度有關。本題判斷的時候偷懶用map,其實自己寫的sp...