New Year and Social Network【Hello 2020 F】【拓扑+LCA+贪心】

2023-11-02

题目链接


  看到比赛的时候zzq大聚聚用了LCT做的,在线%%%

  首先,我们可以发现,两棵大小相同、构造形状不同的树,一定是可以用另一棵树的边来维持这棵树上的每一个点的相互连通性的。我的做法,就是基于这样展开的,

  我们有T1、T2两棵树,现在我们要去用T2树上的边,来代替T1树上的边,使得代替的边能保持原树的连通性。

  看到如图的树左边的T1和右边的T2,两边的颜色相互对应原边与代替边。

  这里用贪心的策略来解决这个问题。

  我们看到如图的T2,对于T2 的叶子结点,它和它的父亲结点,只能用来维护一次联通,那么这个联通应该用在哪里?用在叶子结点往父亲结点最近的点,这是最贪心的策略,譬如说T2图中的2号点和9号点,我们的2号点只能用一次来维护联通了,而剩余的点都是还可以用来维护的,所以,转换到图一中去,我们应该最贪心的将2号点和4号点(图T1)所链接的边用2-9(T2)边代替,尽管它是可以代替(2-4)、(4-7)、(7-9)这条链上的所有的边,但是这样的贪心策略却是最优的。

  我们现在就是想办法去维护这个,那么不妨就是从那些只有一个可以链接的点x开始出发,它在T2中所唯一链接的且没有被使用过的点y,那么,基于贪心的策略,我们将它在T1中的对应x的所在位置,向它的y在T1中所在位置的这一条链找出来,我们要用xy这条边来替换这条链上距离x最近的未被替换的边。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 250005;
int N;
struct Graph
{
    int head[maxN], cnt, du[maxN], root[maxN], fa[maxN][20], deep[maxN];
    inline int _LCA(int u, int v)
    {
        if(deep[u] < deep[v]) swap(u, v);
        int det = deep[u] - deep[v];
        for(int i=log2(det); i>=0; i--)
        {
            if((det >> i) & 1) u = fa[u][i];
        }
        if(u == v) return u;
        for(int i=log2(N); i>=0; i--)
        {
            if(fa[u][i] ^ fa[v][i])
            {
                u = fa[u][i];
                v = fa[v][i];
            }
        }
        return fa[u][0];
    }
    inline int fid(int x) { return x == root[x] ? x : root[x] = fid(root[x]); }
    void init()
    {
        for(int i=1; i<=N; i++)
        {
            head[i] = -1;
            du[i] = 0;
            root[i] = i;
        }
        cnt = 0;
    }
    struct Eddge
    {
        int nex, to;
        Eddge(int a=-1, int b=0):nex(a), to(b) {}
    }edge[maxN << 1];
    inline void addEddge(int u, int v)
    {
        edge[cnt] = Eddge(head[u], v);
        head[u] = cnt++;
    }
    inline void _add(int u, int v) { addEddge(u, v); addEddge(v, u); }
    void dfs(int u, int father)
    {
        fa[u][0] = father; deep[u] = deep[father] + 1;
        for(int i=0; (1 << (i + 1)) < N; i++) fa[u][i + 1] = fa[fa[u][i]][i];
        for(int i=head[u], v; ~i; i=edge[i].nex)
        {
            v = edge[i].to;
            if(v == father) continue;
            dfs(v, u);
        }
    }
}T1, T2;
bool vis[maxN] = {false};
queue<int> Q;
void tp_sort()
{
    for(int i=1; i<=N; i++) if(T2.du[i] == 1) Q.push(i);
    while (Q.size() > 1)    //保证至少有两个端点,保证可以构成边
    {
        int u = Q.front(), x = 0, y = 0; Q.pop();
        vis[u] = true;
        x = u;
        for(int i=T2.head[u], v; ~i; i=T2.edge[i].nex)
        {
            v = T2.edge[i].to;
            if(!vis[v])
            {
                y = v;
                T2.du[v]--;
                if(T2.du[v] == 1) Q.push(v);
            }
        }
        int p = T1._LCA(x, y);
        int fix = T1.fid(x), fiy;
        if(T1.deep[fix] > T1.deep[p])   //如果深度更深,先要保证x与自己的临近父亲的在树上的链接性
        {
            printf("%d %d %d %d\n", T1.fa[fix][0], fix, x, y);
            T1.root[fix] = T1.fid(T1.fa[fix][0]);
        }
        else    //如果深度更浅的话,先要保证上面结点的连通性
        {
            fiy = y;
            for(int i=log2(N); i>=0; i--)
            {
                if(T1.deep[T1.fa[fiy][i]] > T1.deep[p] && (T1.fid(T1.fa[fiy][i]) ^ fix)) fiy = T1.fa[fiy][i];
            }
            printf("%d %d %d %d\n", fiy, T1.fa[fiy][0], x, y);
            T1.root[fiy] = fix;
        }
    }
}
int main()
{
    scanf("%d", &N);
    T1.init(); T2.init();
    for(int i=1, u, v; i<N; i++)
    {
        scanf("%d%d", &u, &v);
        T1._add(u, v); T1.du[u]++; T1.du[v]++;
    }
    for(int i=1, u, v; i<N; i++)
    {
        scanf("%d%d", &u, &v);
        T2._add(u, v); T2.du[u]++; T2.du[v]++;  //保证贪心策略先从度为1的点开始选取
    }
    T1.deep[0] = 0;
    T1.dfs(1, 0);
    printf("%d\n", N - 1);
    tp_sort();
    return 0;
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

New Year and Social Network【Hello 2020 F】【拓扑+LCA+贪心】 的相关文章

  • 【构造】0617 Edge Split

    题意 给定一个 n n n 点 m m m 条边的无向连通图 其中 1
  • [STL]vector常见用法详解

    目录 引入 常见用法介绍 1 vector的定义 2 vector容器内元素的访问 3 vector常用函数实例解析 1 push back 2 pop back 3 size 4 clear 5 insert 6 erase vector
  • HDU--1050:Moving Tables (贪心)

    1 题目源地址 http acm hdu edu cn showproblem php pid 1050 2 解题思路 将每个输入的起始房间和结束房间转换为房间前面的区间 按区间起始位置从小到大排序 首先取第一个区间 后续如果有区间的起始位
  • 西安电子科技大学第二届程序设计新生赛-F-zxy的长跑【欧拉回路】

    题目链接 好极了的欧拉回路 我们想知道怎样才能跑完所有的边 我们可以从度为奇数的点出发 因为这是欧拉回路的无向图的先觉调节 当然 这道题还有另外一种可能就是这是一个环 1 gt 2 2 gt 3 3 gt 4 4 gt 1 那么就没有奇数度
  • BZOJ4868 [Shoi2017]期末考试

    YY一下的话感觉代价关于最晚出分时间是一个单峰函数 三分最晚的出分时间 然后贪心一下算代价就行 如果A gt B就只用B就行了 要不然的话出分时间小于当前限制的都可以随便往后调直到到达限制 那么先尽量用A 调不到限制以内的再用B即可 inc
  • 【01规划】POJ 3621 Sightseeing Cows

    POJ 3621 Sightseeing Cows 题意 给定一张 n 个点 m 条边的有向图 每个点都有一个权值 f i 每条边都有一个权值 t i 求图中的一个环 使 环上各点的权值之和 除以 环上各边的权值之和 最大 输出这个最大值
  • 矩阵树定理

    启蒙 http zhengruioi com contest 1416 T1 T2的10分暴力 后面是论文科技 不搞了 https www luogu com cn problem P6178 O n 3
  • AcWing 378. 骑士放置(最大独立集&&匈牙利算法)

    输入样例 2 3 0 输出样例 4 解析 题意为求最大独立集 即为总点数 最小点覆盖 include
  • POJ 3259 Wormholes(最短路——Bellman-ford)

    A Wormholes While exploring his many farms Farmer John has discovered a number of amazing wormholes A wormhole is very p
  • [图论]---[网络流]---最大权闭合子图

    最大权闭合子图 闭合图的概念 闭合图建立在有向图之上 对于 G V E 选取一个点的子集 V V 的任意一点的所有能到达的点也在集合 V 内 则称 V 为闭合子图 最大权闭合子图即在G的所有闭合子图中 点权和最大的 最大权闭合子图的求法 构
  • [NOI 2015复习][BZOJ 1509][NOI 2003]逃学的小孩(树的直径)

    题目链接 http www lydsy com JudgeOnline problem php id 1509 题目大意 要从一棵树中找出三个点 X Y Z X Y Z 使得 min dis A C dis B C dis A B min
  • King's Quest【POJ 1904】【Tarjan强连通分量】

    Once upon a time there lived a king and he had N sons And there were N beautiful girls in the kingdom and the king knew
  • Codeforces Round #751 (Div. 2) D. Frog Traveler(BFS)

    题解 因为我们最多把所有的点跳一遍么 所以直接BFS模拟一下就行了 注意现在跳的点不能是以前已经跳过的点 并且只能越跳越高 否则没有意义 这样就保证了时间复杂度是线性的 AC代码 include
  • How far away ? 【HDU - 2586】【DFS+链式前向星优化】

    题目链接 其实这道题可以不用链式前向星优化换做vector lt gt 也是可以跑的 只是会许会慢些而已 来换个中文题意好读些 勇气小镇是一个有着n个房屋的小镇 为什么把它叫做勇气小镇呢 这个故事就要从勇气小镇成立的那天说起了 修建小镇的时
  • 1345:香甜的黄油(Dijkstra)---信息学奥赛一本通

    题目描述 农夫John发现做出全威斯康辛州最甜的黄油的方法 糖 把糖放在一片牧场上 他知道N 1 N 500 只奶牛会过来舔它 这样就能做出能卖好价钱的超甜黄油 当然 他将付出额外的费用在奶牛上 农夫John很狡猾 像以前的巴甫洛夫 他知道
  • 714阿里巴巴模拟面试

    介绍一下数据库分页 https www nowcoder com questionTerminal 3577280c810546658f06f19c01ff0345 给定一棵树 求出这棵树的直径 即两个节点距离的最大值 应该是左右子树遍历深
  • 讲解 最大流问题+最小花费问题+python(ortool库)实现

    文章目录 基本概念 图 邻接矩阵 最大流问题 python解决最大流问题 python解决最大流最小费用问题 喜欢的话请关注我们的微信公众号 你好世界炼丹师 公众号主要讲统计学 数据科学 机器学习 深度学习 以及一些参加Kaggle竞赛的经
  • E (1052) : DS树--带权路径和

    文章目录 一 题目描述 二 输入与输出 1 输入 2 输出 三 参考代码 一 题目描述 计算一棵二叉树的带权路径总和 即求赫夫曼树的带权路径和 已知一棵二叉树的叶子权值 该二叉树的带权路径和APL等于叶子权值乘以根节点到叶子的分支数 然后求
  • 860.染色法判定二分图

    二分图是指一个图中的所有顶点可以分为两部分 并且每条边连接的是属于不同部分的两个顶点 include
  • 860.染色法判定二分图

    二分图是指一个图中的所有顶点可以分为两部分 并且每条边连接的是属于不同部分的两个顶点 include

随机推荐

  • AF_PACKET套接字解密 --- 02

    AF PACKET套接字解密 02 2012 05 23 22 36 57 分类 LINUX 当AF PACKET套接字注册了prot hook后 怎样进行监听呢 先来看发送 当协议栈准备将数据交给net device发送时 它将调用dev
  • (一维数组)输入N个数,然后逆序输出

    一维数组 1 输入N个数 例题6个数 然后逆序输出 define N 6 include stdio h void main int i a N t for i 0 i
  • 网络安全-js安全知识点与XSS常用payloads

    目录 简介 用法 JS必备知识 输出与注释 输出 注释 语法 函数 字符串方法 事件 表单 Cookie 代码执行 伪协议 XSS常用payload 普通 双写绕过 编码绕过 html标签绕过正则 参考 写给和我一样学习安全的小白 简介 J
  • eMMC分区管理

    目录 0 概述 FLASH分区类型 分区大小 分区编址 1 Boot Area Partitions 1 1 容量大小 1 2 从 Boot Area 启动 1 2 1 Original Boot Operation 1 2 2 Alter
  • 递归与回溯的理解

    递归 程序调用自身的编程技巧称为递归 recursion 递归做为一种算法在程序设计语言中广泛应用 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法 它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模 较小的问题来求解
  • 忘了高高在上的Chatgpt吧,更香的Claude和Bard来了

    最近LLM这一领域近年来进步神速 新的产品层出不穷 给我们的生活和工作带来了巨大便利 也引发了广泛关注 首当其冲的 就数OpenAI研发的ChatGPT ChatGPT是一款基于GPT模型打造的对话AI系统 被业内公认为目前进展最快 实力最
  • 大多数女生为什么不适合当程序员?

    最重要的一点 逻辑思维能力 女程序员最大的问题不是压力大而是思维方式切换的挑战 从抽象到具象 平常需要将问题抽象出来 运用抽象思维解决工作上的困难 生活中间又要很具象 很感性地和人交往 这是非常难以达到的一件事 加上工作压力一大 就容易崩溃
  • skywalking 实现收集基于python的Django项目链路追踪案例

    一 python3环境设置 1 1 安装python3 apt get update apt install python3 pip y pip install apache skywalking root skywalking agent
  • 人脸相关公开数据集

    1 皮肤分割和面部检测数据集 FSD 1 数据集名称 Face and Skin Detection FSD Database 2D图像 2 数据集简介 The Face and Skin Detection FSD Database is
  • nodejs使用kafka

    什么是卡夫卡 kafka 是一种分布式的 基于发布 订阅的消息系统 消息以消息队列的形式进行发送 如何使用kafka 安装kafka npm i kafka node 配置config 配置kafka的地址和topic 放在config文件
  • 【VQ-VAE论文精读+代码实战】Neural Discrete Representation Learning

    VQ VAE论文精读 代码实战 Neural Discrete Representation Learning 0 前言 Abstract 1 Introduction 提出现有方法的问题并说明有哪些贡献 2 Related Work 提出
  • vue中click无效问题

    当父元素为relative 子元素为absolute时可能会出现click点击无效 无法触发onClick事件的情况 目前已知两种解决方法 1 最外层div的z index层级设置比里面绝对定位的大 2 用 click prevent也是可
  • 【机器学习】特征工程:时间特征构造以及时间序列特征构造(含源代码理解)

    目录 特征工程 时间特征构造以及时间序列特征构造 一 前言 二 特征构造介绍 三 时间特征构造 3 1 连续值时间特征 3 2 离散值时间特征 3 2 1 时间特征拆解 3 2 2 时间特征判断 3 2 3 结合时间维度的聚合特征 四 时间
  • shell浅谈之三for、while、until循环

    一 简介 Shell编程中循环命令用于特定条件下决定某些语句重复执行的控制方式 有三种常用的循环语句 for while和until while循环和for循环属于 当型循环 而until属于 直到型循环 循环控制符 break和conti
  • 【Redis速通】基础知识2 - 常用数据结构

    Redis 通用指令 下面是一些 Redis 的通用命令 你可以根据下表进行简单的复习 键操作命令 SET 设置指定键的值 GET 获取指定键的值 DEL 删除指定键 EXISTS 检查指定键是否存在 KEYS 获取匹配指定模式的键列表 字
  • MyBatis代码生成器-Example讲解

    什么是example类 mybatis generator会为每个字段产生Criterion 为底层的mapper xml创建动态sql 如果表的字段比较多 产生的example类会十分庞大 理论上通过example类可以构造你想到的任何筛
  • Linux JAVA环境的搭建tomcat的部署(含多实例)

    tomcat tomcat是Apache软件基金会项目中的一个核心项目由 Apache Sun 和其他一些公司及个人共同开发而成 tomcat 是 Java 语言开发的 Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器 to
  • 快排和归并排序算法的模板及运用

    快排和归并排序算法的模板及运用 一 快速排序 二 快速选择 三 归并排序 四 逆序对的数量 一 快速排序 核心思想 把一个序列分为两部分 左半部分所有数均小于等于或大于等于右半部分所有数 递归处理左右两部分 具体步骤 其中q为一个数组 l为
  • windows下SSH服务的开启

    本人服务安装环境是win7 启动程序是freeSSHd freeSSHd下载链接如下 链接 https pan baidu com s 18ZNS5PvACo30fYjRhI ZPA 提取码 39e7 运行 exe文件 默认安装即可 安装路
  • New Year and Social Network【Hello 2020 F】【拓扑+LCA+贪心】

    题目链接 看到比赛的时候zzq大聚聚用了LCT做的 在线 首先 我们可以发现 两棵大小相同 构造形状不同的树 一定是可以用另一棵树的边来维持这棵树上的每一个点的相互连通性的 我的做法 就是基于这样展开的 我们有T1 T2两棵树 现在我们要去