[AGC027F]Grafting
题意:给定两棵树,一次操作形如:选一个未被选过的叶子,改变它的一条出边,问能否在第一棵树上做一些操作使得它变成第二棵树,如果能则询问最小操作次数
如果答案不是$n$,那么存在一个点$r$没有被选中过
如果$r$和$v$在两棵树上都相邻,那么我们不会改变$(v,r)$,因为如果改变了那么一定是选中$v$,以后没有办法再把这条边变回来
如果$u$和$v$在两棵树上都相邻,那么我们不会改变$(u,v)$,因为只能选叶子,所以改变这条边一定选$u$,以后要把这条边变回来只能选$v$,而$v$作为叶子的唯一出边是$(v,r)$,所以这条边也不能动
以此类推,我们从$r$开始搜索,只走那些两棵树的公共边,得到的连通块中的边是不会被改变的,连通块中的点同样不会被选中,因为它们作为叶子时唯一的出边已经被硬点为不可改变
剩下的边是一定要改变的,并且改变它只能由选定端点中更深的那个来实现,我们想知道是否存在一个合法的顺序使得按这个顺序选择点能满足每次选到的都是叶子
在第一棵树中,设$fa_x=y$,如果$x,y$都能被选,那么选$y$之前一定要先选$x$,在第二棵树中,如果$fa_x=y$且$x,y$都能被选,那么选$x$之前要先选$y$,把限制关系建成一个有向图,如果没有环就有解了
总时间复杂度$O(n)$,但这样并不能统计到答案为$n$的情况,于是我们再$O(n^2)$枚举第一次操作,被选中的那个点之后就不能选了,于是套用上面的算法即可,总时间复杂度$O(n^3)$
#include<stdio.h> #include<algorithm> #include<string.h> using namespace std; const int inf=2147483646; int fb; struct tree{ int h[60],nex[110],to[110],M; void reset(){ M=0; memset(h,0,sizeof(h)); } void add(int a,int b){ M++; to[M]=b; nex[M]=h[a]; h[a]=M; } int fa[60]; void dfs(int x){ for(int i=h[x];i;i=nex[i]){ if(to[i]!=fa[x]&&to[i]!=fb){ fa[to[i]]=x; dfs(to[i]); } } } }a,b; int d[60],v[60],n,M; bool f[60]; void dfs(int fa,int x){ int i,tm; tm=++M; f[x]=1; for(i=a.h[x];i;i=a.nex[i])v[a.to[i]]=tm; for(i=b.h[x];i;i=b.nex[i]){ if(b.to[i]!=fa&&v[b.to[i]]==tm&&b.to[i]!=fb)dfs(x,b.to[i]); } } struct graph{ int h[60],nex[110],to[110],M; bool v[60],ins[60]; void reset(){ M=0; memset(h,0,sizeof(h)); memset(v,0,sizeof(v)); memset(ins,0,sizeof(ins)); } void add(int a,int b){ M++; to[M]=b; nex[M]=h[a]; h[a]=M; } bool dfs(int x){ v[x]=1; ins[x]=1; for(int i=h[x];i;i=nex[i]){ if(!v[to[i]]){ if(!dfs(to[i]))return 0; }else if(ins[to[i]]) return 0; } ins[x]=0; return 1; } }g; int solve(int r){ fb=r; int i,cnt; memset(a.fa,0,sizeof(a.fa)); a.dfs(r); memset(b.fa,0,sizeof(b.fa)); b.dfs(r); memset(f,0,sizeof(f)); dfs(0,r); g.reset(); cnt=0; for(i=1;i<=n;i++){ if(!f[i]){ if(!f[a.fa[i]])g.add(i,a.fa[i]); if(!f[b.fa[i]])g.add(b.fa[i],i); cnt++; } } for(i=1;i<=n;i++){ if(!g.dfs(i))return inf; } return cnt; } void work(){ int i,j,x,y,ans; scanf("%d",&n); a.reset(); b.reset(); memset(d,0,sizeof(d)); for(i=1;i<n;i++){ scanf("%d%d",&x,&y); a.add(x,y); a.add(y,x); d[x]++; d[y]++; } for(i=1;i<n;i++){ scanf("%d%d",&x,&y); b.add(x,y); b.add(y,x); } ans=inf; for(i=1;i<=n;i++)ans=min(ans,solve(i)); for(i=1;i<=n;i++){ if(d[i]==1){ for(j=1;j<=n;j++){ if(j!=i){ x=a.to[a.h[i]]; a.to[a.h[i]]=j; ans=min(ans,solve(i)+1); a.to[a.h[i]]=x; } } } } if(ans==inf)ans=-1; printf("%d\n",ans); } int main(){ int T; scanf("%d",&T); while(T--)work(); }
[AGC027F]Grafting的更多相关文章
- POJ 3437 Tree Grafting
题意:给出一个深度优先遍历树的up down顺序,求这棵树以及这棵树变为”左子右兄”树的高度 思路:直接dfs,x代表树1的高度,y代表树2的高度 #include<cstdio> #in ...
- web server && web framework角色区分
问题 web framework是否包括webserver? 是否可以包括? webserver 和 framework的关系是? https://www.quora.com/What-is-the- ...
- HOJ题目分类
各种杂题,水题,模拟,包括简单数论. 1001 A+B 1002 A+B+C 1009 Fat Cat 1010 The Angle 1011 Unix ls 1012 Decoding Task 1 ...
- 【Rice】Cultivar versus Variety
From Cindy Haynes, Department of Horticulture As a horticulturist, it is important that I use the ...
- TED_Topic10:The case for engineering our food
By Pamela Ronald Pamela Ronald studies the genes that make plants more resistant to disease and stre ...
- 【Atcoder】AGC027 题解
A - Candy Distribution Again 大意:有x个糖给n个小朋友,必须分完,小朋友得到糖数为一个确切值的时候小朋友会开心,求最多的开心数 题解 直接排序然后贪心分,如果分到最后一个 ...
- SPOJ:Ada and Graft (set合并&优化)
As you might already know, Ada the Ladybug is a farmer. She grows a big fruit tree (with root in 0). ...
- CVPR 2020 全部论文 分类汇总和打包下载
CVPR 2020 共收录 1470篇文章,根据当前的公布情况,人工智能学社整理了以下约100篇,分享给读者. 代码开源情况:详见每篇注释,当前共15篇开源.(持续更新中,可关注了解). 算法主要领域 ...
- CVPR 2020论文收藏(转知乎:https://zhuanlan.zhihu.com/p/112337176)
CVPR 2020 共收录 1470篇文章,根据当前的公布情况,人工智能学社整理了以下约100篇,分享给读者. 代码开源情况:详见每篇注释,当前共15篇开源.(持续更新中,可关注了解). 算法主要领域 ...
随机推荐
- PACM Team(牛客第三场多校赛+dp+卡内存+打印路径)
题目链接(貌似未报名的不能进去):https://www.nowcoder.com/acm/contest/141/A 题目: 题意:背包题意,并打印路径. 思路:正常背包思路,不过五维的dp很容易爆 ...
- 20151024_001_C#基础知识(静态与非静态的区别,值类型和引用类型,堆和栈的区别,字符串的不可变性,命名空间)
1:我们把这些具有相同属性和相同方法的对象进行进一步的封装,抽象出来类这个概念. 类就是个模子,确定了对象应该具有的属性和方法. 对象是根据类创建出来的. 2:类:语法 [public] class ...
- LCD实验学习笔记(六):存储控制器
s3c2440可使用地址空间为1GB(0x00000000到0x40000000). 1G空间分为8个BANK,每个BANK为128MB. 设27条地址线,和8个片选引脚(nGCS0-nGCS7). ...
- bisai2.py
比赛专用py #!/usr/bin/env python #encoding:utf- #by i3ekr import re,requests,os res = "(flag{.*?}&q ...
- 64_l5
libsmartcols-2.29.1-2.fc26.x86_64.rpm 13-Feb-2017 07:04 150590 libsmartcols-devel-2.29.1-2.fc26.i686 ...
- quazip 在windows msvc 2005 下的编译
quazip 在windows msvc 2005 下的编译 http://blog.csdn.net/v6543210/article/details/11661427
- C#中执行批处理文件(.bat),执行数据库相关操作
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- ASPxTreeList的右键按钮事件
ASPxTreeList应该是比较长用的控件了~现在就来说说它的右键按钮事件 这里实现的是右键里有折合和展开所有节点的功能 code: <dx:ASPxTreeList ID="ASP ...
- WP评论系统更换小结(转)
第三方评论插件 多说 多说是一款追求极致体验的社会化评论框,可以用微博.QQ.人人.豆瓣等帐号登录并评论. 多说具备优质用户体验.速度和稳定性.社会化推荐.建站程序审核整合.垃圾评论过滤等特性. 自定 ...
- CentOS7.5***
一.借助谷歌上网助手 二.用ss来实现*** 下载工具 sudo yum install shadowsocks-libev 修改配置文件 sudo chmod 777 /etc/shadowsock ...