题目链接

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. Neo4j Cypher语法(二)

    目录 4 子句 4.1 CREATE 4.2 MATCH 4.3 Match 4.4 Create match return连用来返回一个关系基础 4.5 Optional_match 4.6 Wit ...

  2. StoneTab标签页CAD插件 2.6.0

    1.纯属自娱自乐,未做过多的测试: 2.理论上可以用在CAD2010-2012版本,自己用的是WIN10 64位,CAD2012,其他未过测试: 3.尚未打算支持其他版本CAD,主要是电脑只能装WIN ...

  3. winfrom_根据checkbox勾选项增减dgv字段列

    1.效果: 2.点击‘配置’按钮: private void btn_configure_Click(object sender, EventArgs e) { string sum = string ...

  4. 【原创】大数据基础之Chronos

    官方:https://mesos.github.io/chronos/ mesos集群中替换crontab Chronos A fault tolerant job scheduler for Mes ...

  5. Linux Too many open files

    Linux Too many open files 查看系统资源限制信息: sudo -s -u root -H id sudo -s lsof | awk '{ print $2 " &q ...

  6. EntityFramework学习要点记一

    一.Entity的注解属性(Annotations)不管是code first还是db first,都需要用到注解属性,至于用System.ComponentModel.DataAnnotations ...

  7. [转载]from __future__ import的用法

    一句话概况:这是为了在低版本python中使用高版本特性而引入的,最常用的就是print_function来实现在2.x中使用3.x中的print()命令,从而避免在切换版本时修改代码. https: ...

  8. CSS中为什么有的元素能够设置高度,而有的元素却不能设置高度与宽度?

    可以使用{display:block}将内联元素变为块级元素,同时使用{display:inline}将块级元素变为内联元素. {display:inline-block}又是怎么回事,根据张鑫旭老师 ...

  9. canvas签名

    <template> <div class="share" style="background:#fff"> <div class ...

  10. Delphi Android拍照报错

    打开拍照提示以上错误,解决方式