C. Cover the Tree2020 (dfs序构造) 牛客暑期多校训练营(第二场)

2024-04-16 00:48

本文主要是介绍C. Cover the Tree2020 (dfs序构造) 牛客暑期多校训练营(第二场),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

题意:
求最少的链覆盖所有边

思路:
可以想到任意链都得叶子开始叶子结尾,那么数目肯定是确定的,为叶子数目加一除以二。

可以想到,为了尽可能的覆盖更多变,我们要选宽度尽可能大的叶子相连。这里的宽度我们可以用dfs序表示,选择非叶子节点作为根然后求dfs序,然后两两配对。

但不能是最右边的叶子匹配最左边的叶子,
比如 1->2,1->3, 1->4 , 4->5, 4->6中,1->4边就可能覆盖不到。
所以要 a[i]匹配a[i+len/2]。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <iostream>using namespace std;typedef long long ll;const int maxn = 2e5 + 7;
const int INF = 0x3f3f3f3f;vector<int>G[maxn];
vector<int>Leaf;
int dfn[maxn],cnt;void dfs(int x,int fa) {dfn[x] = ++cnt;for(int i = 0;i < G[x].size();i++) {int v = G[x][i];if(v == fa) continue;dfs(v,x);}
}int cmp(int x,int y) {return dfn[x] < dfn[y];
}int main() {int n;scanf("%d",&n);for(int i = 1;i < n;i++) {int x,y;scanf("%d%d",&x,&y);G[x].push_back(y);G[y].push_back(x);}if(n == 1) {printf("0\n");return 0;}if(n == 2) {printf("1\n1 2\n");return 0;}for(int i = 1;i <= n;i++) {if(G[i].size() == 1) {Leaf.push_back(i);}}int rt = 1;for(int i = 1;i <= n;i++) {if(G[i].size() != 1) {rt = i;break;}}dfs(rt,-1);sort(Leaf.begin(),Leaf.end(),cmp);int len = Leaf.size();printf("%d\n",(len + 1) / 2);for(int i = 0;i < len / 2;i++) {printf("%d %d\n",Leaf[i],Leaf[i + len / 2]);}if(len % 2 == 1) {printf("%d %d\n",Leaf[0],Leaf[len - 1]);}return 0;
}

这篇关于C. Cover the Tree2020 (dfs序构造) 牛客暑期多校训练营(第二场)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/907379

相关文章

hdu 2489 (dfs枚举 + prim)

题意: 对于一棵顶点和边都有权值的树,使用下面的等式来计算Ratio 给定一个n 个顶点的完全图及它所有顶点和边的权值,找到一个该图含有m 个顶点的子图,并且让这个子图的Ratio 值在所有m 个顶点的树中最小。 解析: 因为数据量不大,先用dfs枚举搭配出m个子节点,算出点和,然后套个prim算出边和,每次比较大小即可。 dfs没有写好,A的老泪纵横。 错在把index在d

poj 3050 dfs + set的妙用

题意: 给一个5x5的矩阵,求由多少个由连续6个元素组成的不一样的字符的个数。 解析: dfs + set去重搞定。 代码: #include <iostream>#include <cstdio>#include <set>#include <cstdlib>#include <algorithm>#include <cstring>#include <cm

ural 1149. Sinus Dances dfs

1149. Sinus Dances Time limit: 1.0 second Memory limit: 64 MB Let  An = sin(1–sin(2+sin(3–sin(4+…sin( n))…) Let  Sn = (…( A 1+ n) A 2+ n–1) A 3+…+2) An+1 For given  N print  SN Input One

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

leetcode105 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3/ \9 20/ \15 7   class Solution {public TreeNode buildTree(int[] pr

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

暑期学习总结

iOS学习 前言无限轮播图换头像网络请求按钮的configuration属性总结 前言 经过暑期培训,完成了五个项目的仿写,在项目中将零散的内容经过实践学习,有了不少收获,因此来总结一下比较重要的内容。 无限轮播图 这是写项目的第一个难点,在很多项目中都有使用,越写越熟练。 原理为制造两个假页,在首和尾分别制作最后一页和第一页的假页,当移动到假页时,使用取消动画的方式跳到

深度优先(DFS)和广度优先(BFS)——算法

深度优先 深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支,当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访

代码训练营 Day26 | 47.排序II | 51. N-皇后 |

47.排序II 1.跟46题一样只不过加一个树层去重 class Solution(object):def backtracking(self,nums,path,result,used):# recursion stopif len(path) == len(nums):# collect our setresult.append(path[:])return for i in range(

代码随想录训练营day37|52. 携带研究材料,518.零钱兑换II,377. 组合总和 Ⅳ,70. 爬楼梯

52. 携带研究材料 这是一个完全背包问题,就是每个物品可以无限放。 在一维滚动数组的时候规定了遍历顺序是要从后往前的,就是因为不能多次放物体。 所以这里能多次放物体只需要把遍历顺序改改就好了 # include<iostream># include<vector>using namespace std;int main(){int n,m;cin>>n>>m;std::vector<i