题目链接:点击查看

题目大意:给出一棵树,可以删除 xxx 条边并增加 xxx 条边使得树变为竹子,竹子就是一条链,问 xxx 最小可以为多少,输出一种方案数

题目分析:树上最小路径覆盖,按照子节点个数分两种情况讨论即可:

  1. son[u]==2son[u]==2son[u]==2:删除掉 uuu 和 fa[u]fa[u]fa[u] 这条边即可
  2. son[u]>2son[u]>2son[u]>2:删除掉 uuu 和 fa[u]fa[u]fa[u] ,并且删除掉 son[u]−2son[u]-2son[u]−2 条连向子节点的边

然后剩下的图一定是一个 “竹子森林”,将叶子节点两两相连即可

代码:

// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<list>
#include<unordered_map>
#define lowbit(x) x&-x
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f;
}
template<typename T>
inline void write(T x)
{if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=1e6+100;
vector<pair<int,int>>node[N];
bool del_fa[N],vis[N],ban[N];
vector<pair<int,int>>del,add;
vector<pair<int,int>>leaf;
vector<int>temp_leaf;
int answer=0;
void dfs1(int u,int fa) {int son=0;for(auto it:node[u]) {int v=it.first;int id=it.second;if(v==fa) {continue;}dfs1(v,u);if(del_fa[v]) {ban[id]=true;} else {son++;}}if(son>=2) {del_fa[u]=true;for(auto it:node[u]) {int v=it.first;int id=it.second;if(v==fa) {continue;}if(son<=2) {break;}if(!del_fa[v]) {son--;ban[id]=true;}}}
}
void dfs2(int u,int fa) {int son=0;vis[u]=true;for(auto it:node[u]) {int v=it.first;int id=it.second;if(v==fa) {continue;}if(ban[id]) {continue;}dfs2(v,u);son++;}if(fa==-1&&son==1) {temp_leaf.push_back(u);} else if(son==0) {temp_leaf.push_back(u);}
}
void init(int n) {memset(vis,false,(n+5));memset(ban,false,(n+5));memset(del_fa,false,(n+5));leaf.clear();add.clear();del.clear();for(int i=1;i<=n;i++) {node[i].clear();}
}
int main()
{#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int w;cin>>w;while(w--) {int n;read(n);init(n);for(int i=1;i<n;i++) {int u,v;read(u),read(v);node[u].push_back({v,i});node[v].push_back({u,i});}dfs1(1,-1);for(int i=1;i<=n;i++) {for(auto it:node[i]) {if(ban[it.second]&&it.first<i) {del.push_back({it.first,i});}}}for(int i=1;i<=n;i++) {if(!vis[i]) {temp_leaf.clear();dfs2(i,-1);if(temp_leaf.size()==2) {leaf.push_back({temp_leaf[0],temp_leaf[1]});} else {leaf.push_back({temp_leaf[0],temp_leaf[0]});}}}for(int i=1;i<(int)leaf.size();i++) {add.push_back({leaf[i-1].second,leaf[i].first});}cout<<del.size()<<endl;for(int i=0;i<(int)del.size();i++) {cout<<del[i].first<<' '<<del[i].second<<' '<<add[i].first<<' '<<add[i].second<<endl;}}return 0;
}

CodeForces - 1521D Nastia Plays with a Tree(树上最小路径覆盖)相关推荐

  1. D. Nastia Plays with a Tree(树形dp)

    https://codeforces.com/contest/1521/problem/D 思路: 把树上的单链初始时每个点是一个链.然后类似树形dp递归.递归过程中模拟链的断开,拼凑新的链头链尾. ...

  2. BZOJ 3221: [Codechef FEB13] Obserbing the tree树上询问( 可持久化线段树 + 树链剖分 )

    树链剖分+可持久化线段树....这个一眼可以看出来, 因为可持久化所以写了标记永久化(否则就是区间修改的线段树的持久化..不会), 结果就写挂了, T得飞起...和管理员拿数据调后才发现= = 做法: ...

  3. CodeForces - 1521B Nastia and a Good Array

    B. Nastia and a Good Array time limit per test: 2 seconds memory limit per test: 256 megabytes Nasti ...

  4. SPOJ-COT-Count on a tree(树上路径第K小,可持久化线段树)

    题意: 求树上A,B两点路径上第K小的数 分析: 同样是可持久化线段树,只是这一次我们用它来维护树上的信息. 我们之前已经知道,可持久化线段树实际上是维护的一个前缀和,而前缀和不一定要出现在一个线性表 ...

  5. Codevs 2756 树上的路径

    2756 树上的路径  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述 Description 给出一棵树,求出最小的k,使得,且在树中存在路径P, ...

  6. bzoj3784 树上的路径 点分治+RMQ+优先队列

    题目分析 树上的路径路径?可以,这很点分治. 求最长的mmm条的长度?可以,着很优先队列. 但问题是,用优先队列只能做全局才能保证复杂度是对的,但点分治是分治就不能做全局. 于是对于每次点分治,都记录 ...

  7. Codeforces 739B Alyona and a tree (树上路径倍增及差分)

    题目链接 Alyona and a tree 弄了好几个小时终于Accepted了,之后发现这个题是Div1的. 比较考验我思维的一道好题. 首先,做一遍DFS预处理出t[i][j]和d[i][j]. ...

  8. CodeForces - 932D Tree(树上倍增,好题)

    题目链接:点击查看 题目大意:给出一棵树,初始时只有一个节点1,权值为0,后续有 n 个操作,每次操作分为两种情况: 1 u val:向树中插入一个新的节点,其父节点为 u ,权值为 val 2 u ...

  9. 中石油训练赛 - Russian Dolls on the Christmas Tree(树上启发式合并/主席树)

    题目链接:点击查看 题目大意:给出一棵 n 个节点的树,以点 1 为根,现在对于每个节点作为根的子树求解:子树中有多少个编号不相交的连续子段,如:1 2 4 5 7,共有三个连续的段,分别为 [ 1 ...

最新文章

  1. 百度大规模Service Mesh落地实践
  2. 字符串反序,逆序输出字符串
  3. 数据结构之快速排序图文详解及代码(C++实现)
  4. python多个main方法_Python,main方法未运行(同一文件中有多个类)
  5. CutJS – 用于 HTML5 游戏开发的 2D 渲染引擎
  6. 本硕皆数学专业,博士转行生物后,他发表了学校首篇Nature
  7. STM32学习1之ADC+DMA(使用定时器触发)
  8. 购物车单选全选,计算总价,出现个小问题,没找到.....
  9. 【实践】关于智能蛇的三次尝试
  10. simlink里面MATLAB Function ‘xxx‘ not supported for code generation.
  11. 巴塞罗那,高迪的城市
  12. Android Studio连接mysql8.0.25经验贴(三天血与泪的教训)
  13. 谁在用琵琶弹奏一曲东风破
  14. discord怎么创建账号_如何邀请人们加入Discord服务器(以及创建邀请链接)
  15. IDEA安装数据库插件Database Navigator和IDEA连接数据库
  16. 成功把Ubuntu安装到U盘完整教程!
  17. 数学——埃氏筛与线性筛
  18. 力扣 586. 订单最多的客户
  19. 隐马尔科夫模型,三个基本问题及相应算法
  20. dfont2ttf and ttf2eto

热门文章

  1. 【视频】谷歌大佬30分钟让你入门机器学习(2019谷歌I/O资源分享)
  2. 不要再说找不到前端项目练手了!
  3. mysql 函数 局部变量_MySQL 存储过程 存储函数 局部变量 游标 概念示例
  4. oracle语句优化pl sql语句,求oracle插入初始数据pl/sql语句优化,该怎么处理(2)
  5. springboot基本属性注入
  6. Redis实现分布式Session管理
  7. NioEventLoop 的实例化过程
  8. SpringMVC的数据响应-页面跳转-返回字符串形式(应用)
  9. mysql的length函数和char_length中文字符长度计算函数
  10. 外观模式coding