• sss


    <更新提示>

    <第一次更新>


    <正文>

    树的重心

    我们先来认识一下树的重心。

    树的重心也叫树的质心。找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡。

    根据树的重心的定义,我们可以通过树形DP来求解树的重心。

    (Max_i)代表删去i节点后树中剩下子树中节点最多的一个子树的节点数。由于删去节点i至少将原树分为两部分,所以满足( frac{1}{2}n leq Max_i),我们要求的就是一个(i),使得(Max_i)最小。

    对于Max数组,我们可以列出如下状态转移方程:

    [Max_i=max_{jin son(i)}{size_j,n-size_i} ]

    size数组即为节点个数(树的大小),可以在树形DP中顺带求解。

    (Code:)

    inline void dp(int r,int f)
    {
    	size[r]=1;
    	for(int i=0;i<Link[r].size();i++)
    	{
    		int Son=Link[r][i];
    		if(Son==f)continue;
    		dp(Son,r);
    		size[r]+=size[Son];
    		Max[r]=max(Max[r],size[Son]);
    	}
    	Max[r]=max(Max[r],n-size[r]);
    	if(Max[r]==Max[ans]&&r<ans)ans=r;
    	if(Max[r]<Max[ans])ans=r;
    }
    

    还是通过一道例题来认识一下。

    Balancing Act(POJ1655)

    Description

    The city consists of intersections and streets that connect them.

    Heavy snow covered the city so the mayor Milan gave to the winter-service a list of streets that have to be cleaned of snow. These streets are chosen such that the number of streets is as small as possible but still every two intersections to be connected i.e. between every two intersections there will be exactly one path. The winter service consists of two snow plovers and two drivers, Mirko and Slavko, and their starting position is on one of the intersections.

    The snow plover burns one liter of fuel per meter (even if it is driving through a street that has already been cleared of snow) and it has to clean all streets from the list in such order so the total fuel spent is minimal. When all the streets are cleared of snow, the snow plovers are parked on the last intersection they visited. Mirko and Slavko don’t have to finish their plowing on the same intersection.

    Write a program that calculates the total amount of fuel that the snow plovers will spend.

    Input Format

    The first line of the input contains two integers: N and S, 1 <= N <= 100000, 1 <= S <= N. N is the total number of intersections; S is ordinal number of the snow plovers starting intersection. Intersections are marked with numbers 1...N.

    Each of the next N-1 lines contains three integers: A, B and C, meaning that intersections A and B are directly connected by a street and that street's length is C meters, 1 <= C <= 1000.

    Output Format

    Write to the output the minimal amount of fuel needed to clean all streets.

    Sample Input

    5 2
    1 2 1
    2 3 2
    3 4 2
    4 5 1
    

    Sample Output

    6
    

    解析

    这个就是树的重心的模板题了嘛。

    还有题目的第二问就是重心子树中节点数最多的子树的节点数。嗯!刚好符合我们Max数组的定义,直接输出就可以了。

    (Code:)

    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<vector>
    #include<cstring>
    #define mset(name,val) memset(name,val,sizeof name)
    using namespace std;
    const int N=20000+50;
    int n,size[N],Max[N],ans,cnt;
    vector < int > Link[N];
    inline void input(void)
    {
    	scanf("%d",&n);
    	for(int i=1;i<n;i++)
    	{
    		int x,y;
    		scanf("%d%d",&x,&y);
    		Link[x].push_back(y);
    		Link[y].push_back(x);
    	}
    }
    inline void dp(int r,int f)
    {
    	size[r]=1;
    	for(int i=0;i<Link[r].size();i++)
    	{
    		int Son=Link[r][i];
    		if(Son==f)continue;
    		dp(Son,r);
    		size[r]+=size[Son];
    		Max[r]=max(Max[r],size[Son]);
    	}
    	Max[r]=max(Max[r],n-size[r]);
    	if(Max[r]==Max[ans]&&r<ans)ans=r;
    	if(Max[r]<Max[ans])ans=r;
    }
    int main(void)
    {
    	int T;
    	scanf("%d",&T);
    	while(T--)
    	{
    		mset(Max,0x00);
    		mset(size,0x00);
    		ans=0;cnt=0;Max[0]=0x3f3f3f3f;
    		input();
    		dp(1,0);
    		printf("%d %d
    ",ans,Max[ans]);
    		for(int i=1;i<=n;i++)
    			Link[i].clear();
    	}
    }
    

    <后记>

  • 相关阅读:
    Powerdesigner中如何生成测试数据
    iBatis #和$的区别 把int作为参数时,转换为字符型
    config或者xml中的embedded使用方法。
    C#中发送邮件
    ASP.NET中JSON的序列化和反序列化
    AspNetPager.dll 实现分页
    oracle创建表空间
    如何进行数据库,比如ORACLE,SQL SERVER的逆向工程,将数据库导入到PD中
    DataTable转换成JSON字符串的函数
    iBatis把一个表的sqlmap配置的多个xml中。
  • 原文地址:https://www.cnblogs.com/Parsnip/p/10371480.html
Copyright © 2020-2023  润新知