• P3174 [HAOI2009]毛毛虫


    题目描述

    对于一棵树,我们可以将某条链和与该链相连的边抽出来,看上去就象成一个毛毛虫,点数越多,毛毛虫就越大。例如下图左边的树(图 1 )抽出一部分就变成了右边的一个毛毛虫了(图 2 )。

    输入输出格式

    输入格式:

    在文本文件 worm.in 中第一行两个整数 N , M ,分别表示树中结点个数和树的边数。

    接下来 M 行,每行两个整数 a, b 表示点 a 和点 b 有边连接( a, b ≤ N )。你可以假定没有一对相同的 (a, b) 会出现一次以上。

    输出格式:

    在文本文件 worm.out 中写入一个整数 , 表示最大的毛毛虫的大小。

    输入输出样例

    输入样例#1: 复制
    13 12 
    1 2 
    1 5 
    1 6 
    3 2 
    4 2 
    5 7 
    5 8 
    7 9 
    7 10 
    7 11 
    8 12 
    8 13 
    输出样例#1: 复制
    11

    说明

    40% 的数据, N ≤ 50000

    100% 的数据, N ≤ 300000


    基本上就是用dp找树的直径,只不过是这道题还要加上距离为1的点。

    但是其实是一样的,一共有两种情况:

    1.一个节点x其子树中最大的两条毛毛虫大小之和

    2.一个叶子节点到根节点

    与求直径不同之处在于更新一个点子树中的最长链时还要加上他的兄弟个数

    只要在每一次判断的时候变成f[i]=max(f[t])+size[i]

    #include<iostream>
    #include<stdio.h>
    
    using namespace std;
    
    int k,i,m,n,j,l,a[300004],g,h,cnt,ver[1000005],nex[1000005],head[1000005],f[1000005],w,s[1000005];
    
    void add(int x,int y)
    {
        cnt+=1;
        ver[cnt]=y;
        nex[cnt]=head[x];
        head[x]=cnt;
    }
    
    void dfs(int x,int y)
    {
        int ans=-0x7fffffff;
        for(int i=head[x];i;i=nex[i])
        {
            int t=ver[i];
            if(t==y) continue;
            dfs(t,x);
            k=max(k,f[x]+f[t]+s[x]-1);
            if(f[t]>f[x]) f[x]=f[t];
        }
        if(s[x]<=2) f[x]+=1;
        else f[x]+=s[x]-1;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=m;i++) 
        {
            scanf("%d%d",&g,&h);
            s[g]+=1; s[h]+=1;
            add(g,h);
            add(h,g);
        }
        dfs(1,0);
        printf("%d",max(k,f[1]));
    }
    
  • 相关阅读:
    Python_FTP通讯软件
    Python_NAT
    Python_跟随目标主机IP变换
    Python_网络攻击之端口
    spring
    Java多线程总结之线程安全队列Queue
    队列
    路径
    事务的概念
    GBK,UTF-8,和ISO8859-1之间的编码与解码
  • 原文地址:https://www.cnblogs.com/ZUTTER/p/9309445.html
Copyright © 2020-2023  润新知