#include
int main()
給你一棵無根樹,求有多少點對之間距離<=k。
樹分治。
然後對於乙個重心x。我們把它的全部子樹中的全部點存到結構體陣列中。
結構體中存距離和子樹編號。
第一遍sort,我們雙指標掃哪些點對符合要求。
第二遍sort,我們把同一子樹中還符合要求的點對數目刪掉。
sort是o(
nlog
n)。處理是o(
n)。 然後分治logn層,總時間複雜度o(
nlog
2n)#include
#include
#include
#include
#define n 50100
#define inf 0x3f3f3f3f
using
namespace
std;
int n,m;
struct eli
e[n<<1];
int head[n],cnt;
bool rem[n];
inline
void add(int u,int v,int len)
int f[n],f2[n],son[n];
int treecenter,length;
int dfs1(int x,int p)
else
if(temp>f2[x])
f2[x]=temp;
}return f[x]+1;
}int g[n];
void dfs2(int x,int p)
return ;
}inline
int get_treecenter(int x)
struct summorer
}src[n];
inline
int cmpa(summorer a,summorer b)
return ; } int ans; void work(int x,int n) sort(src+1,src+cnt+1,cmpa); p=n; for(i=0;i<=n;i++) sort(src+1,src+cnt+1,cmpb); src[cnt+1].b=-1; for(i=0;i<=n;i=j) } for(i=head[x];i;i=e[i].next) return ; } void init() int main() work(1,n-1); printf("%d\n",ans); } return
0; }
poj 1741 Tree 樹的分治
解 文中有,就是把路徑分成經過樹根,和不經過樹根兩類,每次處理經過樹根的,然後剩下的子樹部分可以遞迴處理,如果每次選取樹的重心,那麼可以保證最多遞迴logn層。經過樹根的先排序,然後o n 的複雜度就能算出,那麼每層的複雜度nlogn,最多遞迴logn層,總複雜度nlogn 2 include in...
poj 1741 Tree 樹的分治
求樹上倆結點之間距離小於k的結點對個數 倆個點a,b的公共祖先為c,那麼這倆個點的距離就可以用dis a,c dis b,c 表示,我們可以不斷的處理這樣c,然後計算距離,處理點對,為了使平均效能最好,我們需要找的c為每一棵子樹的重心 需要注意的算點對的時候這種方法成立的條件是倆個點不在同一顆子樹上...
POJ 1741 Tree 樹的分治
題目 題意 給定一棵樹,有n個點和n 1條邊,邊有邊權,給出乙個k,求樹上任意兩點間的最短距離不大於k的個數 思路 看了09年漆子超的 利用分治法,每次找樹的重心,重心即是在當前樹中刪掉此點後,節點數最多的子樹的節點數最小,找到重心後,求其所有子孫到其的距離,然後統計一下兩兩之和不大於k的個數,另外...