• 洛谷 P4178 Tree


    洛谷 P4178 Tree

    洛谷传送门

    题目描述

    给定一棵 nn 个节点的树,每条边有边权,求出树上两点距离小于等于 kk 的点对数量。

    输入格式

    第一行输入一个整数 nn,表示节点个数。

    第二行到第 nn 行每行输入三个整数 u,v,wu,v,w ,表示 uu 与 vv 有一条边,边权是 ww

    第 n+1n+1 行一个整数 kk

    输出格式

    一行一个整数,表示答案。


    题解:

    与POJ的那道题是一样的,就是少了个多组数据,还是洛谷好(逃。

    还是点分治入门题,关于点分治:

    详解点分治

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=4*1e4+10;
    int n,k,ans;
    int tot,head[maxn],nxt[maxn<<1],to[maxn<<1],val[maxn<<1];
    bool v[maxn];
    int size[maxn],mp[maxn],dist[maxn];
    int sum,root,s;
    void add(int x,int y,int z)
    {
    	to[++tot]=y;
    	val[tot]=z;
    	nxt[tot]=head[x];
    	head[x]=tot;
    }
    void getroot(int x,int f)
    {
    	size[x]=1,mp[x]=0;
    	for(int i=head[x];i;i=nxt[i])
    	{
    		int y=to[i];
    		if(y==f||v[y])
    			continue;
    		getroot(y,x);
    		size[x]+=size[y];
    		mp[x]=max(mp[x],size[y]);
    	}
    	mp[x]=max(mp[x],sum-size[x]);
    	if(mp[x]<mp[root])
    		root=x;
    }
    void getdis(int x,int f,int d)
    {
    	dist[++s]=d;
    	for(int i=head[x];i;i=nxt[i])
    	{
    		int y=to[i];
    		if(v[y]||y==f)
    			continue;
    		getdis(y,x,d+val[i]);
    	}
    }
    int calc(int x,int len)
    {
    	s=0;
    	memset(dist,0,sizeof(dist));
    	getdis(x,0,len);
    	sort(dist+1,dist+s+1);
    	int l=1,r=s,cnt=0;
    	while(l<=r)
    	{
    		if(dist[r]+dist[l]<=k)
    			cnt+=(r-l),l++;
    		else
    			r--;
    	}
    	return cnt;
    }
    void dfz(int x)
    {
    	ans+=calc(x,0);
    	v[x]=1;
    	for(int i=head[x];i;i=nxt[i])
    	{
    		int y=to[i];
    		if(v[y])
    			continue;
    		ans-=calc(y,val[i]);
    		sum=size[y],root=0;
    		getroot(y,0);
    		dfz(root);
    	}
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<n;i++)
    	{
    		int x,y,z;
    		scanf("%d%d%d",&x,&y,&z);
    		add(x,y,z);
    		add(y,x,z);
    	}
    	scanf("%d",&k);
    	mp[0]=sum=n;
    	getroot(1,0);
    	dfz(root);
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    java中的锁
    CAS机制与自旋锁
    volatile关键字的特性及证明
    java中并发下的集合类
    数据库的分库分表
    浅入理解JVM
    99乘法表
    JAVA实现简单的时间刷新使用线程
    线程的优先级
    线程礼让
  • 原文地址:https://www.cnblogs.com/fusiwei/p/13822204.html
Copyright © 2020-2023  润新知