• 点分治 模板


    poj 1741

    1.选取一个点,把无根树变成有根树。通过树形dp的方式选择。用son记录点的子树大小,用F算出最大的子树,当F[x]<F[root]时,更换root.

    2.再次通过dfs处理树上的deep和距离。

    3.处理连通块中通过根节点的路径。减去同一子树内部的路径。

    4.递归。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <climits>
    
    using namespace std;
    typedef long long ll;
    const int maxn = 10000+5;
    const int maxm = 20000+10;
    bool vis[maxn];
    int head[maxn];
    int nxt[maxm],w[maxm],e[maxm],n,k,root,sum,x,y,z;
    int ans;
    int F[maxn];//sum of son
    int son[maxn];
    int dep[maxn];
    int d[maxn];
    
    void getroot(int x,int fa){
    	son[x]=1;F[x]=0;
    	for(int k=head[x];k!=-1;k=nxt[k]){
    		if(e[k]==fa||vis[e[k]]) continue;
    		getroot(e[k],x);
    		son[x]+=son[e[k]];
    		F[x]=max(F[x],son[x]);
    	}
    	F[x]=max(F[x],sum-F[x]);
    	if(F[x]<F[root]) root=x;
    }
    
    void getdep(int x,int fa){
    	dep[++dep[0]]=d[x];
    	for(int k=head[x];k!=-1;k=nxt[k]){
    		if(e[k]==fa||vis[e[k]]) continue;
    		d[e[k]]=d[x]+w[k];
    		getdep(e[k],x);
    	}
    }
    
    int calc(int x,int v){
    	d[x]=v;dep[0]=0;
    	getdep(x,0);
    	sort(dep+1,dep+1+dep[0]);
    	int l=1,r=dep[0],ret=0;
    	while(l<r){
    		if(dep[r]+dep[l]<=k){
    			ret+=r-l;
    			l++;
    		} else {
    			r--;
    		}
    	}
    	return ret;
    }
    
    void solve(int x){
    	ans+=calc(x,0);
    	vis[x]=1;
    	for(int k=head[x];k!=-1;k=nxt[k]){
    		if(vis[e[k]]) continue;
    		ans-=calc(e[k],w[k]);
    		sum=son[e[k]];
    		root=0;
    		getroot(e[k],0);
    		solve(root);
    	}
    }
    
    int main(){
    	//freopen("in.txt","r",stdin);
    	while(~scanf("%d%d",&n,&k)){
    		if(!n&&!k) break;
    		ans=root=0;
    		memset(vis,0,sizeof vis);
    		memset(head,-1,sizeof head);
    		for(int i=1;i<n;i++){
    			scanf("%d%d%d",&x,&y,&z);
    			e[i]=y;w[i]=z;nxt[i]=head[x];head[x]=i;
    			e[i+n]=x;w[i+n]=z;nxt[i+n]=head[y];head[y]=i+n;
    		}
    		F[0]=INT_MAX;sum=n;
    		getroot(1,0);
    		solve(root);
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    线程阻塞工具:LockSupport
    jenkins
    Mysql中MVCC的使用及原理详解
    你知道 hash 的实现吗?为什么要这样实现?
    为什么哈希表的容量一定要是 2的整数次幂?
    同步异步 阻塞 非阻塞
    MFC
    MFC
    MFC
    MFC
  • 原文地址:https://www.cnblogs.com/foreignbill/p/7821244.html
Copyright © 2020-2023  润新知