首页 > 其他分享 >CF 947 (Div. 1 + Div. 2) D. Paint the Tree

CF 947 (Div. 1 + Div. 2) D. Paint the Tree

时间:2024-05-30 22:24:05浏览次数:13  
标签:ab int 947 Tree dfs dep 顶点 Div

时间: 24_05_30

原题:Codeforces Round 947 (Div. 1 + Div. 2)

标签: 二分/数据结构/[[DFS]]/[[模拟]]/[[树形结构]]

题目大意

有 \(n\) 个顶点的树,初始时每个节点都是白色

树上有两个棋子,为\(P_A\) 和 \(P_B\) ,分别位于 \(a\) , \(b\) 顶点

\(P_A\) 所在的顶点会被涂成红色,\(P_B\) 经过的顶点如果是红色,那么该顶点变成蓝色

每次两棋子各走一步,问最少几次所有顶点会变成蓝色

思路

分解问题

  • 首先解决一个问题,假定 \(P_A\) 和 \(P_B\) 在同一个顶点上,那么最短的路径是多少?

我们可以画个图,要想经过所有顶点,每条路径都要经过两次,除了拘留 \(P_A\) 最远的点

换句话说,以 \(a\) 为根节点,节点数为 \(n\) ,树的最大深度为 \(mx\) ,则此时的最优解为 \(2*(n-1)-mx\)

  • 第二个问题,现在a与b不是同一位置,此时我们需要一个不太严谨的猜想:pa与pb先在ab点碰面,再从ab点出发,此时为最优解

简单的解释一下,思考\(P_A\) 和 \(P_B\) 在整个过程中的运动,最后的答案关键在于 \(P_B\) 点的结束次数

那么不考虑路径重复等复杂问题,先让两点移动到5,再从5开始dfs,可以得到最优答案

解决流程

  1. 以a为根结点dfs造树

  2. 找出最合适的点ab

  3. 以ab为根结点造树

  4. 根据ab找出的mx和从a到ab的cnt找出答案

代码

#include<iostream>
#include<vector>
#include<functional>

using namespace std;
#define int long long
#define endl "\n"

const int N = 2e5 + 10;

int _, n, u, v, a, b;
vector<int>g[N];
vector<int>f(N);//father
vector<int>dep(N);

void solve() {
    cin >> n;
    
    for (int i = 0; i <= n; i++) {
        g[i].clear();
        dep[i] = 0;
        f[i] = 0;
    }
    cin >> a >> b;
    for (int i = 0; i < n - 1; i++) {
        cin >> u >> v;
        g[u].emplace_back(v);
        g[v].emplace_back(u);
    }

    //1. 以a为根结点dfs造树
    function<void(int, int)>dfs = [&](int r, int fa) {
        //先建树
        f[r] = fa;
        //再取dep
        dep[r] = dep[fa] + 1;
        //子树
        for (auto i : g[r])
            if (i != f[r])
                dfs(i, r);
    };
    dfs(a, 0);
    //2. 找出最合适的点ab
    int ab = b;
    int cnt = 0;
    // 根据深度寻找最适合的ab
    while (dep[ab] > (dep[a] + dep[b]) / 2) {
        ab = f[ab];
        cnt++;//同时记录cnt,即a和b走了多少次到达的ab
    }
    //3. 以ab为根结点造树
    dfs(ab, 0);
    
    //4. 根据ab找出的mx和从a到ab的cnt找出答案
    int ans = 1e18;
    for (int i = 1; i <= n; i++) //也可以在dfs中找mx,这里选择遍历一下找出最大深度
        ans = min(ans, 2 * (n - 1) - (dep[i]-1) + cnt);//由于代码中根结点的深度为1,需要减去这个1
    
    cout << ans << endl;
}
signed main() {
    cin >> _;
    while (_--) 
        solve();
    return 0;
}

参考B站

标签:ab,int,947,Tree,dfs,dep,顶点,Div
From: https://www.cnblogs.com/lulaalu/p/18223354

相关文章

  • CF Round946(div3) 题解
    目录946(div3)ABCDEG946(div3)A每个屏幕3X5,可放2个2X2,其余可填7个1X1先算2X2需要多少个屏幕,再算当前屏幕是否可放下所有1X1,根据1X1的量加屏幕.voidfunc(){ inta,b; cin>>a>>b; intans=(b+1)/2; intstp=a-(ans*15-4*b); if(stp>0) ans+=(s......
  • pyqt Qtreeview分层控件
    pyqtQtreeview分层控件介绍效果代码介绍QTreeView是PyQt中的一个控件,它用于展示分层数据,如目录结构、文件系统等。QTreeView通常与模型(如QStandardItemModel、QFileSystemModel或自定义模型)一起使用,以管理数据和提供视图如何显示数据的规则。效果代码from......
  • Educational Codeforces Round 151 (Rated for Div. 2) E
    链接凌晨两点半突然醒了。。然后睡不着了。。躺了一个半小时决定起来啃题解。花了一个小时弄懂了。但是要怎么自己想到还没想好。这个属于计数dp的范围了,我不是很熟悉了。题目大意:有n个盒子,里面装了一些球,球的数量大于等于1且小于n。可以进行一种操作,每次操作可以把一个球移......
  • CF 948 DIV.2 D. XORificator
    考虑对每个设置为1且唯一那么我们发现对于所有的状态都是确定且唯一的那么我们对于每个点假设它为1且为该列唯一对于除它之外的点的状态进行存储又由于这个值过于大我们考虑使用哈希存储那么出现次数最多的值即为答案点击查看代码map<ull,int>cnt;map<ull,pii>pos;void......
  • CF ROUND946 (DIV. 3)D:构造
    Ingenuity-2题面翻译你有两个机器人,分别是Rover(R)和Helicopter(H)。它们初始都在同一平面直角坐标系\(xOy\)的\((0,0)\)处。定义北为\(y\)轴正方向,东为\(x\)轴正方向。现有一串由以下四个字符指令组成的指令串\(s\):N向北移动一步,即\((x,y)\to(x,y+1)......
  • CF Div. 2 C
    CodeforcesRound948(Div.2)C.NikitaandLCM标签暴力枚举数据结构[[数学]]题目大意有长度为n的数组a,求a中最长子序列的长度,子序列要满足\(lcm(subArray(a))\notina\)\(1\len\le2000\),\(1\lea_i\le10^9\),对于t个测试案例,\(sum(n)\le2000\)思路1.......
  • codeforces round 948(Div2)
    A题目过简单,略B.构造+二进制点击查看代码#include<bits/stdc++.h>#defineLLlonglongLLx,ans[40];boolyes[40];intmain(){std::ios::sync_with_stdio(0),std::cin.tie(0);intT;std::cin>>T;while(T--){std::cin>>x;for(LLi......
  • Codeforces Round 948 (Div. 2)
    A.LittleNikita题意:\(n\)步操作,\(+1\)或\(-1\),最终结果是否等于\(m\)思路:设\(+1\)的操作次数为\(x\),\(-1\)的操作次数为\(y\)\[x+y=n\\x-y=m\]\[x=(n+m)/2\\y=(n-m)/2\]\((n-m)\)和\((n+m)\)均为偶数,即\(n\)和\(m\)均为偶数或同为奇数,且\(n>=m\)代码:voidsolve()......
  • Codeforces Round 948 (Div. 2) B - C
    总结:做了A,B,然后开局A看错题wa了一发,B出的又很慢,所以掉大分。总的来说还是c没开出来。B.BinaryColouring1.题目大意:给你一个int范围内的数x,要求构造一个二进制串,能有-1、1、0,二进制串的值不能出现两个连续的地方不为0,二进制串的值要等于x。2.思路分析:我们可以发现,对于x的......
  • codeforces round 948(div.2)
    https://m1.codeforces.com/contest/1977A:题意:小男孩尼基塔得到了一些立方体作为礼物。他决定用它们建一座塔。一开始,塔上没有任何立方体。在一次移动中,尼基塔要么正好把1 个立方体放到塔顶,要么正好从塔顶移走1个立方体。有没有可能在走了n 步之后,塔顶正好有m 个立......