AGC 014E.Blue and Red Tree(思路 启发式合并)
\(Description\)
给定两棵\(n\)个点的树,分别是由\(n-1\)条蓝边和\(n-1\)条红边组成的树。求\(n-1\)次操作后,能否把蓝树变成红树。
每次操作是,选择当前树上一条只由蓝边组成的简单路径\(u\to v\),删掉路径上的任意一条蓝边,然后在路径上任选两个点,在这两个点之间加一条红边。
\(n\leq10^5\)。
\(Solution\)
模拟一下样例二,就比较容易想到:
考虑能否从红树变回到蓝树。
我们每次要找到当前树上一条蓝边组成的路径\(u\to v\),设路径上任意一点是\(a\),不在路径上的一个点是\(b\)。如果当前\(a,b\)之间有红边相连,而\(b\)与路径上某点\(c\)在蓝树上有边,显然这条红边\((a,b)\)是可以通过删掉\((b,c)\)加入的,也就是现在我们在当前树上删掉边\((a,b)\),加入边\((b,c)\)。然后继续找蓝边路径继续扩展。
怎么实现这一过程呢?
对于整条蓝边组成的路径\(u\to v\),我们不需要管具体有哪些点,只需要知道\(b\)与\(u\to v\)之间既有一条红边,也有一条蓝边(不会有两条红边/蓝边啊,因为每次操作后也是一棵树),然后我们可以删掉这条红边,加入这条蓝边。边具体是哪条也不需要管,我们只需要知道\(b\)被加入了路径\(u\to v\)。
所以就可以用并查集实现。\(b\)被合并到路径\(u\to v\)前,要把与\(b\)相连的所有边连到路径\(u\to v\)(的代表点)上去,可以用启发式合并。
同时有红边和蓝边与路径相连,就是这条边出现了两次。所以我们把出现两次的边拿出来扩展就好了。
能扩展\(n-1\)次则可行,否则不行。
启发式合并然后用set维护出边,复杂度\(O(n\log^2n)\)。出边可以hash点对\((u,v)\)来维护,少一个\(\log\),懒得写了。。
//287ms 25472KB
#include <set>
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=1e5+5;
int fa[N];
std::set<int> st[N];
std::pair<int,int> q[N];
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
int Find(int x)
{
return x==fa[x]?x:fa[x]=Find(fa[x]);
}
int main()
{
const int n=read();
int h=0,t=0;
for(int i=n-1<<1; i; --i)
{
int u=read(),v=read();
// if(u>v) std::swap(u,v);
if(!st[u].count(v)) st[u].insert(v), st[v].insert(u);
else q[t++]=std::make_pair(u,v);
}
for(int i=1; i<=n; ++i) fa[i]=i;
while(h<t)
{
int x=Find(q[h].first),y=Find(q[h++].second);
if(st[x].size()<st[y].size()) std::swap(x,y);//x<-y
for(std::set<int>::iterator it=st[y].begin(); it!=st[y].end(); ++it)
if(*it!=x)
{
int u=x,v=*it;
st[v].erase(y);
// if(u>v) std::swap(u,v);
if(!st[u].count(v)) st[u].insert(v), st[v].insert(u);
else q[t++]=std::make_pair(u,v);
}
st[x].erase(y), fa[y]=x;
}
puts(t==n-1?"YES":"NO");
return 0;
}
AGC 014E.Blue and Red Tree(思路 启发式合并)的更多相关文章
- AT2377 Blue and Red Tree
AT2377 Blue and Red Tree 法一:正推 红色的边在蓝色的树上覆盖,一定每次选择的是覆盖次数为1的边的覆盖这条边的红色边连出来 覆盖次数可以树剖找到 这条红色边,可以开始的时候每个 ...
- AtCoder AGC014E Blue and Red Tree (启发式合并)
题目链接 https://atcoder.jp/contests/agc014/tasks/agc014_e 题解 完了考场上树剖做法都没想到是不是可以退役了... 首先有一个巨难写的据说是\(O(n ...
- AGC014E Blue and Red Tree
题意 There is a tree with \(N\) vertices numbered \(1\) through \(N\). The \(i\)-th of the \(N−1\) edg ...
- AtCoder Grand Contest 014 E:Blue and Red Tree
题目传送门:https://agc014.contest.atcoder.jp/tasks/agc014_e 题目翻译 有一棵有\(N\)个点的树,初始时每条边都是蓝色的,每次你可以选择一条由蓝色边构 ...
- 【AGC014E】Blue and Red Tree
Description 给定一棵\(n\)个节点的蓝边树,再给定一棵\(n\)个节点的红边树.请通过若干次操作将蓝树变成红树.操作要求和过程如下: 1.选定一条边全为蓝色的路径: 2.将路径上的一条蓝 ...
- [AT2377] [agc014_e] Blue and Red Tree
题目链接 AtCoder:https://agc014.contest.atcoder.jp/tasks/agc014_e 洛谷:https://www.luogu.org/problemnew/sh ...
- [atAGC014E]Blue and Red Tree
不断删除重边,然后将两个点的边集启发式合并(要考虑到两棵树),合并时发现重边就加入队列,最后判断是否全部删完即可 1 #include<bits/stdc++.h> 2 using nam ...
- dsu on tree 树上启发式合并 学习笔记
近几天跟着dreagonm大佬学习了\(dsu\ on\ tree\),来总结一下: \(dsu\ on\ tree\),也就是树上启发式合并,是用来处理一类离线的树上询问问题(比如子树内的颜色种数) ...
- dsu on tree[树上启发式合并学习笔记]
dsu on tree 本质上是一个 启发式合并 复杂度 \(O(n\log n)\) 不支持修改 只能支持子树统计 不能支持链上统计- 先跑一遍树剖的dfs1 搞出来轻重儿子- 求每个节点的子树上有 ...
随机推荐
- tensorflow(3):神经网络优化(ema,regularization)
1.指数滑动平均 (ema) 描述滑动平均: with tf.control_dependencies([train_step,ema_op]) 将计算滑动平均与 训练过程绑在一起运行 train_o ...
- Nginx详解二十六:Nginx架构篇之性能优化
一.性能优化考虑点 1.当前系统结构瓶颈 通过压力测试观察指标.日志检测.性能分析 2.了解业务模式 接口业务类型.系统层次化结构 3.性能与安全 二.ab接口压力测试工具 1.安装:yum -y i ...
- OrCAD Capture CIS 16.6 导出BOM
OrCAD Capture CIS 16.6 一.选择设计文件:菜单:Tools > Bill of Materials... 二.Bill of Materials > Open in ...
- excel生成数据
Sub function1()Dim i As LongFor i = 1 To 1000000Cells(i, 1) = "A" & iCells(i, 2) = &qu ...
- jenkins权限管理,实现不同用户组显示对应视图views中不同的jobs
如何分组管理权限,如何实现不同用户组显示对应视图views中不同的jobs,建议使用Role Strategy Plugin插件. 1.安装Role Strategy Plugin插件. 2.“系统管 ...
- C/C++中二进制与文本方式打开文件的区别
二进制与文本文件主要有两个大的区别: 1.换行符的区别: Windows平台下 对于Windows文本文件,它们使用回车和换行来表示换行符:如果以“文本”方式打开文件,当读取文件的时候,系统会将所有 ...
- [BZOJ3011][Usaco2012 Dec]Running Away From the Barn
题意 给出一棵以1为根节点树,求每个节点的子树中到该节点距离<=l的节点的个数 题解 方法1:倍增+差分数组 首先可以很容易的转化问题,考虑每个节点对哪些节点有贡献 即每次对于一个节点,找到其第 ...
- 精简版自定义 jquery
function $(id) { var el = 'string' == typeof id ? document.getElementById(id) : id; el.on = function ...
- Hbase的写入负载均衡
在写Hbase的时候,会担心数据分布在各个region上不均匀(与预分区无关): 这个时候可能想到的方式:hash.加盐等(当然是可以的,但是读取的时候咋办呢? 哪天写一个这样的文章) 本文采用新方式 ...
- python 类、函数的引用
类的引用 一.同级目录引用: from 文件名 import 类名 如果报错,原因基本上就是:pycharm不会将当前文件目录自动加入自己的sourse_path. 解决方法: ...