首页 > 其他分享 >CF14D题解

CF14D题解

时间:2023-02-07 21:22:19浏览次数:58  
标签:dis1 dis2 CF14D int 题解 void 路径 max

CF14D Two Paths题解

题目链接

传送门

题意简述

给定一棵树,找出两条不经过相同点的最长路径,使得他们的长度乘积最大。

题目分析

首先,如果在一棵树上,两条路径没有共同的点,那么这两条路径对应的两个深度更小的端点之间一定有唯一一条路径,我们只需要删掉这条路径上任意一条边,就可以分离这两个路径。
看到两秒的时间限制和 \(n \le 200\) 的数据范围,我们可以想到暴力删除每一条边,在分成的两颗子树中找到直径即可。

关于如何找到直径,有两种方法,请参考oi_wiki中相关内容

此外,在删边找直径时,为了方便,我们可以直接将删掉的边 \(e\) 的两个端点 \(u\) 和 \(v\) 授予子孙关系,这样在 dfs 的时候就不会遍历到另一棵树上了。

代码示例

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define max_n 300
//以下为读入输出优化模板
void read(int &p)
{
    p = 0;
    int k = 1;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-')
        {
            k = -1;
        }
        c = getchar();
    }
    while (c >= '0' && c <= '9')
    {
        p = p * 10 + c - '0';
        c = getchar();
    }
    p *= k;
    return;
}
void write_(int x)
{
    if (x < 0)
    {
        putchar('-');
        x = -x;
    }
    if (x > 9)
    {
        write_(x / 10);
    }
    putchar(x % 10 + '0');
}
void writesp(int x)
{
    write_(x);
    putchar(' ');
}
void writeln(int x)
{
    write_(x);
    putchar('\n');
}
//以上为读入输出优化模板
//需要开两个记录边的vector,e 在删边时使用,edge 在 dfs 的时候使用
vector<pair<int,int>> e;
vector<int> edge[max_n];
int n;
int dis1[max_n],dis2[max_n];//求树的直径需要用到的辅助数组,dis1[i]为从i开始最长的边,dis2[i]为从i开始第二长的边
int max_d = 0;//记录树的直径
void dfs(int u,int fa)
{
    dis1[u] = dis2[u] = 0;//初值都为0
    for(auto v:edge[u])//遍历与u相连的每一个点 等价于 for(int i = 0;i<edge[u].size();i++) v = edge[u][i]
    {
        if(v == fa)
        {
            continue;
        }  
        dfs(v,u);
        int now = dis1[v] +1;//这条路径的长度
        if(now>dis1[u])//大于最长路分别更新最长路和次长路
        {
            dis2[u] = dis1[u];
            dis1[u] = now;
        }
        else if(now > dis2[u])//大于次长路更新次长路
        {
            dis2[u] = now;
        }
    }

    max_d = max(max_d,dis1[u] + dis2[u]);//最后一条经过u的路径的最大长度即为最长路加次长路
}
signed main()
{
    //测试用
    #if _clang_
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
    #endif

    read(n);
    int u,v;
    for(int i = 1;i<n;i++)
    {
        read(u),read(v);
        //分别加边
        e.push_back({u,v});
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    int d1 = 0,d2 = 0,ans = 0;
    for(int i = 1;i<n;i++)
    {
        //一定要初始化!
        memset(dis1,0,sizeof(dis1));
        memset(dis2,0,sizeof(dis2));
        max_d = 0;
        //找e[i-1].first所在子树的直径
        dfs(e[i-1].first,e[i-1].second);
        d1 = max_d;
        ////找e[i-1].second所在子树的直径
        max_d = 0;
        dfs(e[i-1].second,e[i-1].first);
        d2 = max_d;
        ans = max(ans,d1*d2);
    }
    writeln(ans);
    return 0;
}

标签:dis1,dis2,CF14D,int,题解,void,路径,max
From: https://www.cnblogs.com/yuhang-ren/p/17099841.html

相关文章

  • CF1785B Letter Exchange 题解(思维+模拟)
    题目链接难度:绿+。题意给定\(t\)组testcase,每组testcase如下。有\(m\)个长度为3的字符串,每个字符都是\(\text{w}\)、\(\text{i}\)、\(\text{n}\)中的一个,一......
  • HDU5126 stars题解
    HDU5126Description\(T\)组数据,给一个空的三维空间,\(Q\)次操作,分为插入一个点和查询某个立方体内点的个数。\(T\le10,Q\le5\times10^4\)Sol题目没说强制在线......
  • CF1333F Kate and imperfection 题解 线性筛
    题目链接:http://codeforces.com/problemset/problem/1333/F题目大意:kate有一个集合S,S中的元素是1到n的整数她认为集合S的一个子集M的集合的不完美值等于\(\max_{a,b\in......
  • 消息队列的延时以及过期失效,消息队列消息积压及占满问题解决思路
    大量消息在mq里积压了几个小时了还没解决几千万条数据在MQ里积压了七八个小时,从下午4点多,积压到了晚上11点多。这个是我们真实遇到过的一个场景,确实是线上故障了......
  • CF1787I Treasure Hunt 题解
    题目链接题意描述:定义一个序列的权值为一段前缀与一段子段,满足要么前缀与子段不交,要么完全包含的和的最大值,给定一个序列\(a\),求\(a\)的所有子区间的权值和\(n\le1......
  • Django关于站点管理Admin Site的常见问题解决方法
    1.改变django默认语言的方法?仅需添加’django.middleware.locale.LocaleMiddlewar’到MIDDLEWARE_CLASSES设置中,并确保它在’django.contrib.sessions.middleware.Session......
  • Android 软键盘弹出时布局内指定内容上移实现及问题解决
    AndroidSDK目前提供的软键盘弹出模式接口只有两种:一是弹出时自动回冲界面,将所有元素上顶,一种则是不重绘界面,直接将控件元素遮住,没有其他模式,如果......
  • CF1137F Matches Are Not a Child's Play 题解
    以最后被删去的点为根,这样子不会存在从父亲然后删掉某个点,儿子的删除顺序一定比父亲前。记每个点子树中的最大值为\(f_x\),那么一个点的排名,首先就需要加上\(<f_x\)的所......
  • robotframe环境搭建及问题解决
     1.安装pipinstallrobotframeworkipinstallrobotframework-ride进入C:\Python37\Scripts目录下,右击ride.py,选择使用python打开。出现RIDE界面表示RIDE安装成功。......
  • ABC288 EFG 题解
    E注意到后面选对前面的答案没有影响,而且前面选的顺序对后面的影响是连续的一段(如选2个,那么对应的\(c\)就应该是\(c[i-2..i]\)(对应\(i\)是1、2、3个选时的答案))然......