zoukankan      html  css  js  c++  java
  • poj1741Tree 点分治

      上午学习了点分治,写了1个半小时终于写出一个代码--poj1741,可以说是个模板题。

      分治:对于每个儿子找出重心,分别处理

      注意:1.每次处理一个重心后,ans减去对它儿子的处理 

          原因:因为统计方法没管是否在同一棵树上,所以答案有重复

         2.每次寻找新的重心时,树的大小变化,重新计算大小,否则TLE

    CODE:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    #include<cmath>
    #define ll long long
    #define inf 2147483647
    #define N 10005
    using namespace std;
    int n,k,dis[N],f[N],siz[N],vis[N],rt,ans,size;
    struct node{
    	int v,w;
    };
    vector<int>d;
    vector<node>g[N];
    
    
    void getrt(int u,int fa){
    	siz[u]=1;f[u]=0;
    	for(int i=0;i<g[u].size();i++){
    		int v=g[u][i].v;
    		if(vis[v]||v==fa)continue;
    		getrt(v,u);
    		siz[u]+=siz[v];
    		f[u]=max(f[u],siz[v]);
    	}
    	f[u]=max(f[u],size-siz[u]);
    	if(f[u]<f[rt])rt=u;
    }
    
    
    void getdis(int u,int fa){
    	d.push_back(dis[u]);
    	for(int i=0;i<g[u].size();i++){
    		int v=g[u][i].v,w=g[u][i].w;
    		if(vis[v]||v==fa)continue;
    		dis[v]=dis[u]+w;
    		getdis(v,u);
    	}
    }
    
    int cal(int u,int fir){
    	int ret=0;
    	d.clear();
    	dis[u]=fir;
    	getdis(u,0);
    	int l=0,r=d.size()-1;
    	sort(d.begin(),d.end());
    	while(l<r){
    		while(d[l]+d[r]>k&&l<r)r--;
    		ret+=r-l;l++;
    	}
    	return ret;
    	
    }
    
    void work(int u){
    	ans+=cal(u,0);
    	vis[u]=1;
    	for(int i=0;i<g[u].size();i++){
    		int v=g[u][i].v,w=g[u][i].w;
    		if(vis[v])continue;
    		ans-=cal(v,w);
    		f[0]=size=siz[u];
    		getrt(v,rt=0);
    		work(rt);
    	}
    }
    
    int main(){
    	while(1){
    		scanf("%d%d",&n,&k);
    		if(!n)break;
    		for(int i=1;i<=n;i++)
    		g[i].clear(),vis[i]=0;
    		int u,v,w;
    		for(int i=1;i<n;i++)
    		scanf("%d%d%d",&u,&v,&w),
    		g[v].push_back(node{u,w}),
    		g[u].push_back(node{v,w});
    		ans=0;f[0]=size=n;
    		getrt(1,rt=0);
    		work(rt);
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    SQL中的数字格式化 (收藏)
    read about用法
    run into用法
    shoot for用法
    take off用法
    英语成语
    bring up用法
    satisfy with用法
    spend用法
    Linux环境进程间通信:共享内存
  • 原文地址:https://www.cnblogs.com/wsy01/p/6782137.html
Copyright © 2011-2022 走看看