标签:else size ons 分治策略 class namespace algo 题目 ace
题目大意:给定一棵 N 个节点的无根树,边有边权,统计树上边权和不大于 K 的路径数。
对于每条树上路径,对于每一个点来说,该路径只有经过该点和不经过该点两种情况,对于不经过该点的情况,可以转化成是否经过以该点为树根的子树节点的子问题,由此构成一个分治策略。
对于点分治来说,限制算法复杂度的瓶颈之一是递归的层数,即:子问题的数目。因此,为了避免树退化成一条链,应该每次选取一棵树的重心作为根节点,进行递归求解。层数可以控制在 \(O(logn)\) 级别。
在统计经过每一个点的路径数量时,应该从答案中减去没有经过该点的路径数量,即:减去路径端点在同一棵子树的答案贡献值。
代码如下
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define cls(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=1e4+10;
const int inf=0x3f3f3f3f;
inline int read(){
int x=0,f=1;char ch;
do{ch=getchar();if(ch==‘-‘)f=-1;}while(!isdigit(ch));
do{x=x*10+ch-‘0‘;ch=getchar();}while(isdigit(ch));
return f*x;
}
struct node{
int nxt,to,w;
}e[maxn<<1];
int tot=1,head[maxn];
inline void add_edge(int from,int to,int w){
e[++tot].nxt=head[from],e[tot].to=to,e[tot].w=w,head[from]=tot;
}
int n,k,sn,root,ans,cnt,size[maxn],f[maxn],deep[maxn],d[maxn],vis[maxn];
void read_and_parse(){
for(int i=1;i<n;i++){
int from=read(),to=read(),val=read();
add_edge(from,to,val),add_edge(to,from,val);
}
}
void get_root(int u,int fa){
size[u]=1,f[u]=0;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;if(vis[v]||v==fa)continue;
get_root(v,u);
f[u]=max(f[u],size[v]);
size[u]+=size[v];
}
f[u]=max(f[u],sn-size[u]);
if(f[u]<f[root])root=u;
}
void get_deep(int u,int fa){
deep[++cnt]=d[u];
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;if(v==fa||vis[v])continue;
d[v]=d[u]+e[i].w;
get_deep(v,u);
}
}
int calc(int u,int now){
d[u]=now,cnt=0;
get_deep(u,0);
sort(deep+1,deep+cnt+1);
int l=1,r=cnt,src=0;
while(l<r){
if(deep[l]+deep[r]<=k)src+=r-l,++l;
else --r;
}
return src;
}
void dfs(int u){
ans+=calc(u,0),vis[u]=1;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;if(vis[v])continue;
ans-=calc(v,e[i].w);
sn=size[v];
root=0,get_root(v,0);
dfs(root);
}
}
void solve(){
sn=n,root=0,f[0]=inf;
get_root(1,0);
dfs(root);
printf("%d\n",ans);
}
void init(){
cls(vis,0);cls(head,0);
tot=1,ans=0,root=0;
}
int main(){
while(1){
init();
n=read(),k=read();
if(!(n+k))break;
read_and_parse();
solve();
}
return 0;
}
标签:else size ons 分治策略 class namespace algo 题目 ace
原文地址:https://www.cnblogs.com/wzj-xhjbk/p/9912367.html