zoukankan      html  css  js  c++  java
  • POJ 1741 Tree ——点分治

    【题目分析】

        这貌似是做过第三道以Tree命名的题目了。

        听说树分治的代码都很长,一直吓得不敢写,有生之年终于切掉这题。

        点分治模板题目。自己YY了好久才写出来。

        然后1A了,开心o(* ̄▽ ̄*)ブ

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define maxn 20005
    #define inf 0x3f3f3f3f
    using namespace std;
    
    int n,k,h[maxn],to[maxn],ne[maxn],w[maxn],en,cnt;
    int a[maxn],b[maxn],ban[maxn],siz[maxn],size,root;
    int mx[maxn],now,now_mx,tot;
    
    void init(){en=cnt=0;memset(h,-1,sizeof h);memset(ban,0,sizeof ban);}
    void add(int a,int b,int c){to[en]=b;w[en]=c;ne[en]=h[a];h[a]=en++;}
    void rd(){for(int i=1;i<n;++i){int a,b,c;scanf("%d%d%d",&a,&b,&c);add(a,b,c);add(b,a,c);}}
    
    void dfs_size(int o,int fa)
    {
    	siz[o]=1;
    	mx[o]=0;
    	for (int i=h[o];i>=0;i=ne[i])
    	if (to[i]!=fa&&!ban[to[i]]){
    		dfs_size(to[i],o);
    		siz[o]+=siz[to[i]];
    		mx[o]=max(mx[o],siz[to[i]]);
    	}
    }
    
    void dfs_root(int o,int fa)
    {
    	int now=max(mx[o],size-siz[o]);
    	if (now<now_mx) now_mx=now,root=o;
    	for (int i=h[o];i>=0;i=ne[i]) if (to[i]!=fa&&!ban[to[i]]) dfs_root(to[i],o);
    }
    
    void dfs_dist(int o,int fa,int dist)
    {
    	a[++tot]=dist;
    	for (int i=h[o];i>=0;i=ne[i])
    		if (to[i]!=fa&&!ban[to[i]])
    			dfs_dist(to[i],o,dist+w[i]);
    }
    
    int cal()
    {
    	int ret=0,j=tot;
    	sort(a+1,a+tot+1);
    	for (int i=1;i<=tot;++i)
    	{
    		while (a[j]+a[i]>k&&j) j--;
    		ret+=j;
    		if (j>i) ret--;
    	}
    	return ret/2;
    }
    
    void dfs(int o)
    {
    	dfs_size(o,0);
    	size=siz[o];
    	now_mx=inf;
    	dfs_root(o,0);
    	ban[root]=1;
    	for (int i=h[root];i>=0;i=ne[i])
    	{
    		if (!ban[to[i]])
    		{
    			tot=0;
    			dfs_dist(to[i],root,w[i]);
    			cnt-=cal();
    		}
    	}
    	tot=0;
    	dfs_dist(root,0,0);
    	cnt+=cal();
    	for (int i=h[root];i>=0;i=ne[i])
    		if (!ban[to[i]])
    			dfs(to[i]);
    }
    
    int main()
    {
    	while (scanf("%d%d",&n,&k)!=EOF&&n&&k)
    	{
    		init();rd();dfs(1);
    		printf("%d
    ",cnt);
    	}
    }
    

      

  • 相关阅读:
    VC++ 读取UTF-8和ANSI编码文件
    Swift中Singleton的实现
    Swift详解之NSPredicate
    swift中的as?和as!
    Swift中的init方法
    Swift属性
    罗列系统中的所有字体
    Swift 中的Range和NSRange不同
    In line copy and paste to system clipboard
    苹果开发者账号那些事儿(一)
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6360941.html
Copyright © 2011-2022 走看看