题目链接

https://atcoder.jp/contests/agc014/tasks/agc014_e

题解

完了考场上树剖做法都没想到是不是可以退役了。。。

首先有一个巨难写的据说是\(O(n\log^3n)\)的树剖+树套树做法:

对于每条红边\((u,v)\), 给蓝树上两点间路径\(+1\), 然后每次选出一个值为\(1\)的边,找到覆盖它的红边然后把这条\(1\)的边断掉加上红边,再去掉红边的影响。

下面来说正解。

依然是上面的思路,然后发现假设断掉前\((i-1)\)条蓝边之后形成的联通块的集合是\(B_i\), 连上从第\(i\)条到第\(n\)条的红边之后形成的连通块集合是\(R_i\), 那么答案为YES当且仅当对于任意\(2\le i\le n\), \(R_i=B_i\).

于是可以得到如下转化: 一开始图上有\(n\)个点\(2(n-1)\)条边,若两条边重合则把其连接的两点缩成同一点,问整个图最后能不能缩成一个点。

启发式合并即可。维护目前所有重边的队列、每个点的相邻点以及图上所有的边。每次从队列里取出一条边,然后把度数较小的点的边全部转移到度数较大的点上。如果能如此重复做\((n-1)\)次,那么答案是YES, 否则为NO. 相邻点可以用set维护,图上边可以用map维护。

时间复杂度\(O(n\log^2n)\).

代码

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cassert>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<utility>
#define pii pair<int,int>
#define mkpr make_pair
using namespace std; const int N = 1e5;
multiset<int> ae[N+3];
map<pii,int> g;
queue<pii> que;
int n; void insertedge(int u,int v)
{
if(u==v) return;
if(u>v) swap(u,v);
ae[u].insert(v); ae[v].insert(u);
g[mkpr(u,v)]++;
if(g[mkpr(u,v)]==2) {que.push(mkpr(u,v));}
} void deleteedge(int u,int v)
{
ae[v].erase(ae[v].find(u));
if(u>v) swap(u,v);
if(g.count(mkpr(u,v))) {g.erase(mkpr(u,v));}
} int main()
{
scanf("%d",&n);
for(int i=1; i<=2*(n-1); i++)
{
int u,v; scanf("%d%d",&u,&v);
insertedge(u,v);
}
for(int i=1; i<n; i++)
{
while(1)
{
if(que.empty()) {puts("NO"); return 0;}
int u = que.front().first,v = que.front().second; que.pop();
if(!g.count(mkpr(u,v))) {continue;}
if(ae[u].size()<ae[v].size()) swap(u,v);
for(set<int>::iterator i=ae[v].begin(); i!=ae[v].end(); i++)
{
int x = *i;
deleteedge(v,x);
insertedge(u,x);
}
break;
}
}
puts("YES");
return 0;
}

AtCoder AGC014E Blue and Red Tree (启发式合并)的更多相关文章

  1. AGC014E Blue and Red Tree

    题意 There is a tree with \(N\) vertices numbered \(1\) through \(N\). The \(i\)-th of the \(N−1\) edg ...

  2. AT2377 Blue and Red Tree

    AT2377 Blue and Red Tree 法一:正推 红色的边在蓝色的树上覆盖,一定每次选择的是覆盖次数为1的边的覆盖这条边的红色边连出来 覆盖次数可以树剖找到 这条红色边,可以开始的时候每个 ...

  3. AGC 014E.Blue and Red Tree(思路 启发式合并)

    题目链接 \(Description\) 给定两棵\(n\)个点的树,分别是由\(n-1\)条蓝边和\(n-1\)条红边组成的树.求\(n-1\)次操作后,能否把蓝树变成红树. 每次操作是,选择当前树 ...

  4. AtCoder Grand Contest 014 E:Blue and Red Tree

    题目传送门:https://agc014.contest.atcoder.jp/tasks/agc014_e 题目翻译 有一棵有\(N\)个点的树,初始时每条边都是蓝色的,每次你可以选择一条由蓝色边构 ...

  5. 【AGC014E】Blue and Red Tree

    Description 给定一棵\(n\)个节点的蓝边树,再给定一棵\(n\)个节点的红边树.请通过若干次操作将蓝树变成红树.操作要求和过程如下: 1.选定一条边全为蓝色的路径: 2.将路径上的一条蓝 ...

  6. [AT2377] [agc014_e] Blue and Red Tree

    题目链接 AtCoder:https://agc014.contest.atcoder.jp/tasks/agc014_e 洛谷:https://www.luogu.org/problemnew/sh ...

  7. [atAGC014E]Blue and Red Tree

    不断删除重边,然后将两个点的边集启发式合并(要考虑到两棵树),合并时发现重边就加入队列,最后判断是否全部删完即可 1 #include<bits/stdc++.h> 2 using nam ...

  8. 【AGC014E】Blue and Red Tree 并查集 启发式合并

    题目描述 有一棵\(n\)个点的树,最开始所有边都是蓝边.每次你可以选择一条全是蓝边的路径,删掉其中一条,再把这两个端点之间连一条红边.再给你一棵树,这棵树的所有边都是红边,问你最终能不能把原来的树变 ...

  9. AGC 014 E Blue and Red Tree [树链剖分]

    传送门 思路 官方题解是倒推,这里提供一种正推的做法. 不知道你们是怎么想到倒推的--感觉正推更好想啊QwQ就是不好码 把每一条红边,将其转化为蓝树上的一条路径.为了连这条红边,需要保证这条路径仍然完 ...

随机推荐

  1. Java进阶开发-基于Base64的加密与解密操作

    基于Base64的加密与解密操作 正常来讲加密基本上永远伴随着解密,所谓的加密或者解密往往都是需要有一些所谓的规则.在JDK1.8开始提供有一组新的加密处理操作,Base64处理.在这个类里面有两个内 ...

  2. Bootstrap3基础教程 03 导航栏

    Bootstrap导航栏 创建一个默认的导航栏的步骤如下: 1.向 <nav> 标签添加 class .navbar..navbar-default. 2.向上面的元素添加 role=&q ...

  3. Eclipse 快捷键、文档注释、多行注释的快捷键

    关于快捷键 Eclipse 的很多操作都提供了快捷键功能,我们可以通过键盘就能很好的控制 Eclipse 各个功能: 一.多行注释快捷键 1.选中你要加注释的区域,用ctrl+shift+C 或者ct ...

  4. Java学习笔记【一、环境搭建】

    今天把java的学习重新拾起来,一方面是因为公司的项目需要用到大数据方面的东西,需要用java做语言 另一方面是原先使用的C#公司也在慢慢替换为java,为了以后路宽一些吧,技多不压身 此次的学习目标 ...

  5. MySQL踩坑及MySQL解压版安装

    MySQL默认当前时间: MySQL5.5版本以下是不支持:datetime default now() 的,只能写成 timestamp default now() ; 而MySQL5.6以上是支持 ...

  6. Java十进制转二进制

    闲着没事写了个简单的十进制转二进制的算法,很简单,个人记录一下,不妥之处请指正. public static String toBinaryString(int j) { if (j < 0) ...

  7. linux 网卡相关命令

    1. ifconfig //查看网络相关信息 2. ifconfig eth0 192.168.1.103 netmask 255.255.255.0 //配置eth0的IP地址 3. route - ...

  8. 记一次自启动的docker容器将宿主机的开机用户登录界面覆盖事件

    宿主机的系统为CentOS7_7.7.1908,默认为GUI启动,安装了宝塔面板,docker-ce为最新版. 在启动了一个centos7的容器(镜像为centos官方镜像)后,将该容器重启策略设置为 ...

  9. 利用PyMySQL模块操作数据库

    连接到数据库 import pymysql # 创建链接得到一个链接对象 conn = pymysql.Connect( host="127.0.0.1", # 数据库服务器主机地 ...

  10. springboot集成redis使用redis作为session报错ClassNotFoundException类RememberMeServices

    springboot 集成redis使用redis作为缓存,会报错的问题. 错误信息: java.lang.IllegalStateException: Error processing condit ...