BZOJ4121 乱搞
来源:互联网 发布:淘宝店铺质检报告没有 编辑:程序博客网 时间:2024/05/17 02:59
这道题两问 (我乱猜的第二问 也不知道证的对不对 OJ上交不过 本机测是可以过得 哪位dalao看出错了请指出Orz)
第一问的话 答案是ans=(叶子结点数+1)/2 将叶子节点两两连接就没有度数位1的点 就可以满足
第二问我的思路是找一个度数>=2的点作为根来dfs 遇到叶子节点 ++cnt 并存在数组里 做完后 ans=(cnt+1)/2 将 i与ans+i 连接 如果是奇数个点 (也就是第ans个点没有对应点可以连) 将ans点与1连
下面证明可行性
这个图画的比较正常 能说明问题就行了
首先我们把每个叶子结点分类 每个点属于他到根路径上离跟最近的点
这个图 1,2,3,4,5,6属于a 7,8属于b 9,10属于c
有几种情况 下面一一讨论
①i点和 ans+i点不属于同一类 那么两个点的lca在根 也就是说切掉两点间路径上任意一个点 这两个点一定联通 这个图也一定联通 比如(2,7)
②i点和 ans+i点属于同一类 那么i到ans+i之间的都属于同一类
比如说(1,6) 很明显中间属于一类
因为是dfs的 很容易得到 先连上两点 继续向下做直到j和ans+j点时两个点不属于同一类 那么j和ans+j就属于情况① 现在回过头来看i和ans+i 因为j在i和ans+i之间 所以j在i和 ans+i之间 那么lca(i,ans+i)一定是lca(i,j)和lca(j,ans+i)上面(或者相同)的点 如果想使(i和ans+i)不连通 就一定要 切在lca(i,ans+i)到根路径上的边 这样他两才有可能不联通 如果切断 通过上面lca的判断 lca(i,ans+i)的儿子点一定可以不经过lca(i,ans+i)移动到j点 这样就和ans+j联通了 也就和整棵树联通了
③每队i和ans+i独属于同一类 很明显这种情况就是所有儿子都属于同一类 那岂不是说根只有一个儿子 这不满足我们一开始选取度数大于2的点作为根的条件 矛盾
④如果ans位奇数 那ans点和第一个叶子结点连就好了 这个很明显成立
这几种情况都说明了 不管切那个边 如果i和ans+i 都在之下 那就情况②证明 如果只有一个在 那直接通过我们之前连接的边就能和树联通
所以贪心成立 也一定有连接ans次的方案(之前我们只是假设 现在说明一定可行)
下面贴代码 很好写
#include<bits/stdc++.h>using namespace std;const int N=5e5+5;int n,tot=1,cnt,ans,tt;int head[N],tmp[N],in[N];bool vis[N];queue<int>s;struct Egde{ int v,nxt;}e[N*2];inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}void add(int u,int v){ e[++tot].v=v;e[tot].nxt=head[u];head[u]=tot;in[v]++; e[++tot].v=u;e[tot].nxt=head[v];head[v]=tot;in[u]++;}void bfs(){ for(int i=1;i<=n;i++){ if(in[i]>=2){ s.push(i);vis[i]=1;break; } } while(!s.empty()){ int x=s.front();s.pop(); if(in[x]==1) tmp[++cnt]=x; for(int i=head[x];i;i=e[i].nxt){ int j=e[i].v; if(!vis[j]){ vis[j]=1; s.push(j); } } }}int main(){/* freopen("data.in","r",stdin); freopen("data.out","w",stdout);*/ n=read(); for(int i=1,x,y;i<n;i++) x=read(),y=read(),add(x,y); bfs(); ans=(cnt+1)>>1; cout<<ans<<endl; for(int i=1;i<=ans;i++){ if(i*2<=cnt) printf("%d %d\n",tmp[i],tmp[ans+i]); else printf("%d %d\n",tmp[1],tmp[ans]); } }
- BZOJ4121 乱搞
- 乱搞
- 乱搞
- qbxt Day 4 乱搞+乱搞+乱搞
- BZOJ4104【乱搞】
- 乱搞题
- 树上乱搞
- 乱搞hash
- 乱搞题
- 代码乱搞
- 乱搞 寿司
- 乱搞题目
- qbxt Day 1 乱搞+乱搞+DP
- HDU1538------水题,乱搞之
- hdu4618Palindrome Sub-Array(乱搞)
- hdu4714 Tree2cycle 树上乱搞
- HDU 5042 分段乱搞
- HDOJ 4696 Answers 乱搞
- 监听器配置文件web.xml引发java.lang.ClassNotFoundException
- java学习——可视化日历的制作
- quill-editor 在ios下editor不能够聚焦输入
- Linux: mv, rename单次及批次修改档案名称及后缀(批量修改文件名)
- xgboost原理及应用
- BZOJ4121 乱搞
- c++学习之 类中的常成员与静态成员
- 卷积网络深度和宽度修改(一)
- 最长非上升/非下降子序列(O(nlogn)非连续)
- Head First Java 39页猜数字游戏中的错误。
- Vue学习之源码分析--Vue.js异步更新DOM策略及nextTick(八)
- [agc009e]Eternal Average
- Socket
- 细说mysql索引