poj1741(樹上點分治)

2021-08-21 13:28:11 字數 1399 閱讀 9366

題解:樹上分治就是一直找重心,然後計算經過重心點的答案有多少,接著再把重心這個點刪除掉然後接著在對應子樹上接著重複上面步驟直到沒有孩子結點。

我是根據下面這篇部落格學習的

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

#define mes(a,b) memset(a,b,sizeof(a))

#define rep(i,a,b) for(int i = a; i <= b; i++)

#define dec(i,a,b) for(int i = b; i >= a; i--)

#define pb push_back

#define fi first

#define se second

#define ls rt<<1

#define rs rt<<1|1

#define lson ls,l,mid

#define rson rs,mid+1,r

#define lowbit(x) x&(-x)

typedef double db;

typedef long long int ll;

typedef pairpii;

typedef unsigned long long ull;

const ll inf = 0x3f3f3f3f;

const int mx = 1e4+5;

const int mod = 1e9+7;

const int x_move = ;

const int y_move = ;

int n,m,len,sum;

int s[mx];

int dp[mx];

int maxson[mx];

int sz[mx];

bool vis[mx];

vectorg[mx];

int root;

void get_root(int u,int fa)

maxson[u] = max(maxson[u],sum-sz[u]);

if(!root||maxson[u]m) r--;

else ans += r-i,i++;

} return ans;

}int get_ans(int u)

return ans;

}int main()

sum = n;

root = 0;get_root(1,0);

printf("%d\n",get_ans(root));

} return 0;

}

poj1741 點分治 樹上點對)

題目大意 一顆樹,問由多少個點對 u,v 滿足dis u,v k 樹的點分治。求先求以重心為根的樹中滿足dis u,v k的點對數,減去重心為根的所有子樹中滿足條件的點對數,即為路徑經過重心的點對數,加起來即為答案。每次對以重心為根的樹進行dfs,子樹大小減半,再以同樣的方式每棵dfs子樹,所以遞迴...

樹上的分治 poj1741

樹是一種優美的資料結構 嗯嗯,這句話看過百遍了 這道題目的描述很清晰,給你一顆n個點 n 10000 有邊權的無根樹,要你統計滿足距離不超過k的點對個數 因為有多組資料的存在,所以平方的演算法是不行的,便向nlogn靠近 貌似用什麼nb資料結構可以o n 天啊。仔細分析了一下,其實是看了 對於每個滿...

POJ 1741 樹的分治

題意就是求樹上距離小於等於k的點對有多少個 n2的演算法肯定不行,因為1w個點 這就需要分治。可以看09年漆子超的 本題用到的是關於點的分治。乙個重要的問題是,為了防止退化,所以每次都要找到樹的重心然後分治下去,所謂重心,就是刪掉此結點後,剩下的結點最多的樹結點個數最小。每次分治,我們首先算出重心,...