题目传送门:https://agc014.contest.atcoder.jp/tasks/agc014_e

题目翻译

有一棵有\(N\)个点的树,初始时每条边都是蓝色的,每次你可以选择一条由蓝色边构成的简单路径,让这条路径的两个端点间连上一条红边,然后断开这条路径上的某条蓝边。这样做\(N-1\)次,就可以把原本的蓝树变成红树。现在给你蓝树和红树的样子,问你可不可能把给出的蓝树变成给出的红树。\(N\leqslant 10^5\)

题解

先膜一发大佬的题解:https://blog.csdn.net/sadnohappy/article/details/79478193

也许是昨天状态不好……想了一下午都想不出……就去看题解了……

思路想到一半卡住了,看了题解的最后一步思路之后不知道怎么实现,我觉得我还是太菜了。

先讲讲我一个\(O(N^2logn)\)的暴力吧:

因为每次连红边都要保证两点之间有一条完全由蓝边构成的简单路径,然后断开某条蓝边。所以我们把所有路径都丢到树上去差分一下,然后求出每条边被多少条路径覆盖,每次把只被覆盖一次的蓝边断开,然后把那一条唯一的覆盖它的红边的差分影响消去,更新一下差分值。这样子如果做不了\(N-1\)次就是\(NO\),否则\(YES\)。

顺着这个思路往下想,既然我可以知道顺着怎么一条一条边断开,我当然也可以知道逆着怎么一条一条边接上来。然后我自己就想不出接下来该怎么办了。

因为最后一条断开的边肯定是红蓝都一样的,那么我假设这个蓝边一开始就不存在,然后把这条蓝边链接的两个点合成一个点,把所有边的信息都更新一下,我们会发现接下来删的蓝边应该也会存在一条红边对应。这样做\(N-1\)次就行了。因为我是倒着做的,所以之前被我印点的断开的边在现在被我选中的路径上还是连上的。

至于实现,看代码吧……我基本不用\(stl\)的……但是我真的不知道还有什么别的实现方法……

时间复杂度:\(O(NlogN)\)

空间复杂度:\(O(N)xinxi\)

代码如下:

#include <set>
#include <map>
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef pair<int,int> pii; const int maxn=1e5+5; int n;
int fa[maxn];
queue<pii> q;
set<int>s[maxn];
map<pii,int>cnt;
set<int>::iterator it; int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
} int find(int x) {
if(fa[x]==x)return x;
return fa[x]=find(fa[x]);
} int main() {
n=read();
for(int i=1;i<2*n-1;i++) {
int x=read(),y=read();
s[x].insert(y),s[y].insert(x);
if(x>y)swap(x,y);
pii tmp=make_pair(x,y);
cnt[tmp]++;
if(cnt[tmp]==2)q.push(tmp);
}
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<n;i++) {
if(q.empty()) {puts("NO");return 0;}
int x=0,y=0;
for(;x==y;x=find(q.front().first),y=find(q.front().second),q.pop());
if(s[x].size()>s[y].size())swap(x,y);fa[x]=y;//启发式合并,保证每条边最多被合并logn次
for(it=s[x].begin();it!=s[x].end();it++) {
int v=*s[x].find(*it);
s[v].erase(s[v].find(x));
if(v==y)continue;
s[v].insert(y),s[y].insert(v);
pii tmp;
if(v>y)tmp=make_pair(y,v);
else tmp=make_pair(v,y);
cnt[tmp]++;
if(cnt[tmp]==2)q.push(tmp);
}//更新边的信息
}
puts("YES");
return 0;
}

AtCoder Grand Contest 014 E:Blue and Red Tree的更多相关文章

  1. AtCoder Grand Contest 014 D:Black and White Tree

    题目传送门:https://agc014.contest.atcoder.jp/tasks/agc014_d 题目翻译 给你一棵树,每次任选一个点染色,先手染白色,后手染黑色.如果最后存在一个白色的点 ...

  2. AtCoder Grand Contest 014

    AtCoder Grand Contest 014 A - Cookie Exchanges 有三个人,分别有\(A,B,C\)块饼干,每次每个人都会把自己的饼干分成相等的两份然后给其他两个人.当其中 ...

  3. AtCoder Grand Contest 009 D:Uninity

    题目传送门:https://agc009.contest.atcoder.jp/tasks/agc009_d 题目翻译 定义只有一个点的树权值为\(0\),若干棵(可以是\(0\)棵)权值为\(k\) ...

  4. AtCoder Grand Contest 009 E:Eternal Average

    题目传送门:https://agc009.contest.atcoder.jp/tasks/agc009_e 题目翻译 纸上写了\(N\)个\(1\)和\(M\)个\(0\),你每次可以选择\(k\) ...

  5. AtCoder Grand Contest 004 C:AND Grid

    题目传送门:https://agc004.contest.atcoder.jp/tasks/agc004_c 题目翻译 给你一张网格图,指定的格子是紫色的,要求你构造出两张网格图,其中一张你可以构造一 ...

  6. AtCoder Grand Contest 028 A:Two Abbreviations

    题目传送门:https://agc028.contest.atcoder.jp/tasks/agc028_a 题目翻译 给你两个串\(s\)与\(t\),长度分别为\(n,m\).问你存不存在一个串长 ...

  7. AtCoder Grand Contest 002 F:Leftmost Ball

    题目传送门:https://agc002.contest.atcoder.jp/tasks/agc002_f 题目翻译 你有\(n*k\)个球,这些球一共有\(n\)种颜色,每种颜色有\(k\)个,然 ...

  8. AtCoder Grand Contest 013 C:Ants on a Circle

    题目传送门:https://agc013.contest.atcoder.jp/tasks/agc013_c 题目翻译 给你一个周长为\(L\)的圆,有\(N\)只蚂蚁在圆上爬,速度为一单位距离每秒. ...

  9. AtCoder Grand Contest 010 C:Cleaning

    题目传送门:https://agc010.contest.atcoder.jp/tasks/agc010_c 题目翻译 给你一棵树,每个点有个权值,每次操作可以选择两个度数为\(1\)的结点,然后让这 ...

随机推荐

  1. 2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告

    2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh ...

  2. sql的一些知识_高级

    1.视图 http://www.cnblogs.com/wang666/p/7885934.html 2.存储过程 http://www.cnblogs.com/wang666/p/7920748.h ...

  3. C 标准库 - <stddef.h>

    C 标准库 - <stddef.h> 简介 stddef .h 头文件定义了各种变量类型和宏.这些定义中的大部分也出现在其它头文件中. 库变量 下面是头文件 stddef.h 中定义的变量 ...

  4. MySQL命令学习(一)

    今天我们来学习一下MySQL中的经常使用命令(MySQL中的命令keyword是不区分大写和小写的): (1)show databases; 显示MySQL中的全部database (2)create ...

  5. ArcGIS 10.1系列产品 升级安装至 ArcGIS 10.2

    概要 分享ArcGIS10.1系列产品(包括desktop.engine.server)升级到ArcGIS10.2的过程,并提供安装ArcGIS10.2安装的详细文档下载链接和crack需要的文件: ...

  6. Unity3D总结:关于射线碰撞

    方法一:Physics.Raycast 光线投射 1.static function Raycast (origin : Vector3, direction : Vector3, distance  ...

  7. 微信小程序 如何使用globalData

    微信小程序在JavaScript文件中声明的变量和函数只在该文件中有效:不同的文件中可以声明相同名字的变量和函数,不会互相影响.如果希望在各个页面之间共同使用某些信息,并且可以对共享数据进行修改设置, ...

  8. Server.xml配置详解

    <Server port="8005" shutdown="SHUTDOWN"> <!-- 属性说明 port:指定一个端口,这个端口负责监听 ...

  9. PythonCookBook笔记——数据结构和算法

    数据结构和算法 解包赋值 p = [1, 2, 3] a, b, c = p # _表示被丢弃的值 _, d, _ = p # 可变长解包 *a, b = p # 字串切割解包 line = 'nob ...

  10. 《UNIX 网络编程 第二版》编译环境的搭建( 运行本专栏代码必读 )

    第一步:搭建基本的编译环境 安装gcc, g++, bulid-essential等编译软件 第二步:下载本书示例源码包 可在这里下载http://ishare.iask.sina.com.cn/f/ ...