洛谷P3806 模板 點分治1 點分治

2022-02-27 21:24:09 字數 1474 閱讀 4730

感謝hzwer的點分治互測。

給定一棵有n個點的樹

詢問樹上距離為k的點對是否存在。

輸入格式:

n,m 接下來n-1條邊a,b,c描述a到b有一條長度為c的路徑

接下來m行每行詢問乙個k

輸出格式:

對於每個k每行輸出乙個答案,存在輸出「aye」,否則輸出」nay」(不包含引號)

輸入樣例#1:

複製

2 1

1 2 2

2

輸出樣例#1:

複製

aye

對於30%的資料n<=100

對於60%的資料n<=1000,m<=50

對於100%的資料n<=10000,m<=100,c<=1000,k<=10000000

比較常規的一道點分治【然而我又因為一些奇奇怪怪的錯誤調了半天】

先以重心為根,對每個子樹dfs統計到根的路徑長度,將這些長度丟進hash表裡【偷懶的我用了stl】,對於每個子樹,在丟進去之前,查詢之前子樹是否存在路徑 = k - d,存在則ok

之後往子樹重心分治

#include#include#include#include#include#define ll long long int

#define rep(i,n) for (int i = 1; i <= (n); i++)

#define redge(u) for (int k = h[u]; k != -1; k = ed[k].nxt)

using namespace std;

const int maxn = 10005,maxm = 10000005,inf = 1000000000;

inline int rd()

while (c >= 48 && c <= 57)

return out * flag;

}int n,m,h[maxn],ne = 0,f[maxn],siz[maxn],rt = 0,sum,vis[maxn];

int d[maxn],id[maxn],k,cnt;

bool flag;

maph;

struct edgeed[maxm];

inline void build(int u,int v,int w); h[u] = ne++;

ed[ne] = (edge); h[v] = ne++;

}void getrt(int u,int f)

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

if (f[u] < f[rt]) rt = u;

}void dfs(int u,int f)

}void solve(int u)

rep(i,cnt) h[d[id[i]]]++;

}redge(u) if (!vis[to = ed[k].to])

}int main()

return 0;

}

洛谷 P3806 模板 點分治1

this way 點分治模板 點分治解決的好像大部分是樹上路徑問題 網上模板有很多,我就不贅述了,大致思想就是找到樹的重心,然後o n 地求出路徑經過這個點的所有情況,之後再將樹以這個重心為基準分成多個子樹,再找到他們的重心,如此分治的去做。網上的 各不相同,我找了同集訓隊的人的寫法,用set維護每...

洛谷 P3806 模板 點分治1

洛谷傳送門 給定一棵有 nn 個點的樹,詢問樹上距離為 kk 的點對是否存在。第一行兩個數 n,mn,m。第 22 到第 nn 行,每行三個整數 u,v,wu,v,w,代表樹上存在一條連線 uu 和 vv 邊權為 ww 的路徑。接下來 mm 行,每行乙個整數 kk,代表一次詢問。對於每次詢問輸出一行...

洛谷 P3806 模板 點分治1

感謝hzwer的點分治互測。給定一棵有n個點的樹 詢問樹上距離為k的點對是否存在。輸入格式 n,m 接下來n 1條邊a,b,c描述a到b有一條長度為c的路徑 接下來m行每行詢問乙個k 輸出格式 對於每個k每行輸出乙個答案,存在輸出 aye 否則輸出 nay 不包含引號 輸入樣例 1 複製2 1 1 ...