题目描述

  给你一棵\(n\)个点的树,让你加最少的边,使得图中没有割点。

  要求输出方案。

  \(n\leq 500000\)

题解

  把叶子的权值设为\(1\),其他点设为\(0\),找出带权重心。

  以重心为根DFS,算出每棵子树的叶子节点个数。

  设有\(l\)个叶子节点。易证每棵子树叶子节点个数不会超过\(\lfloor\frac{l}{2}\rfloor\)。

  把子树按叶子节点个数从大到小排序,从第二大的子树开始,每棵子树选一个叶子和前面剩余最多叶子的子树中选一个叶子连一条边。

  易证这样操作完后重心就不是割点,且剩余叶子最多的子树叶子不会超过总剩余叶子个数\(\div 2\)(向上取整)。

  证明的话,显然次大叶子个数$\geq \(最大叶子个数\)-1$。

  然后就每次选两个剩余叶子个数最多的子树连起来就好了。

  时间复杂度:可以做到\(O(n)\)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<utility>
#include<vector>
#include<queue>
using namespace std;
typedef pair<int,int> pii;
struct graph
{
int v[1000010];
int t[1000010];
int h[500010];
int n;
graph()
{
memset(h,0,sizeof h);
n=0;
}
void clear(int x)
{
for(int i=1;i<=x;i++)
h[i]=0;
n=0;
}
void add(int x,int y)
{
n++;
v[n]=y;
t[n]=h[x];
h[x]=n;
}
};
graph g;
int s[500010];
int f[500010];
int d[500010];
int rt,rtsz;
int tot;
vector<int> b[500010];
int h[500010];
void dfs(int x,int fa)
{
f[x]=fa;
s[x]=0;
if(d[x]==1)
s[x]++;
for(int i=g.h[x];i;i=g.t[i])
if(g.v[i]!=fa)
{
dfs(g.v[i],x);
s[x]+=s[g.v[i]];
}
}
void dfs2(int x)
{
int mx=0;
for(int i=g.h[x];i;i=g.t[i])
if(g.v[i]!=f[x])
{
mx=max(mx,s[g.v[i]]);
dfs2(g.v[i]);
}
mx=max(mx,tot-s[x]);
if(d[x]>1)
{
if(mx<rtsz)
{
rtsz=mx;
rt=x;
}
}
}
void dfs(int x,int fa,int y)
{
if(d[x]==1)
b[y].push_back(x);
else
for(int i=g.h[x];i;i=g.t[i])
if(g.v[i]!=fa)
dfs(g.v[i],x,y);
}
int e[500010];
int cmp(int x,int y)
{
return b[x].size()>b[y].size();
}
vector<int> c[500010];
int ans[500010][2];
priority_queue<pii> q;
void solve()
{
int n;
scanf("%d",&n);
g.clear(n);
for(int i=1;i<=n;i++)
d[i]=0;
for(int i=1;i<=n;i++)
b[i].clear();
for(int i=1;i<=n;i++)
c[i].clear();
int cnt=0;
int x,y;
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
d[x]++;
d[y]++;
g.add(x,y);
g.add(y,x);
}
dfs(1,0);
tot=s[1];
rtsz=0x7fffffff;
dfs2(1);
int t=0;
for(int i=g.h[rt];i;i=g.t[i])
{
dfs(g.v[i],rt,g.v[i]);
e[++t]=g.v[i];
}
sort(e+1,e+t+1,cmp);
for(int i=1;i<=t;i++)
h[i]=b[e[i]].back();
c[b[e[1]].size()].push_back(1);
int now=b[e[1]].size();
for(int i=2;i<=t;i++)
{
while(!c[now].size())
now--;
int y=c[now].back();
c[now].pop_back();
ans[++cnt][0]=b[e[i]].back();
if(b[e[i]].size()>=1)
b[e[i]].pop_back();
c[b[e[i]].size()].push_back(i);
if(b[e[y]].size()==0)
ans[cnt][1]=h[y];
else
ans[cnt][1]=b[e[y]].back();
if(b[e[y]].size()>=1)
b[e[y]].pop_back();
now=max(now,(int)b[e[i]].size());
c[b[e[y]].size()].push_back(y);
if(ans[cnt][0]==ans[cnt][1])
printf("1\n");
}
while(!q.empty())
q.pop();
for(int i=1;i<=t;i++)
if(b[e[i]].size())
q.push(pii(b[e[i]].size(),i));
while(!q.empty()&&q.top().first>=1)
{
pii x=q.top(),y;
q.pop();
if(!q.empty()&&q.top().first>=1)
{
y=q.top();
q.pop();
}
else
if(x.second==1)
y=pii(0,2);
else
y=pii(0,1);
ans[++cnt][0]=b[e[x.second]].back();
b[e[x.second]].pop_back();
if(b[e[y.second]].size()==0)
ans[cnt][1]=h[y.second];
else
{
ans[cnt][1]=b[e[y.second]].back();
b[e[y.second]].pop_back();
}
x.first--;
y.first--;
if(x.first>0)
q.push(x);
if(y.first>0)
q.push(y);
if(ans[cnt][0]==ans[cnt][1])
printf("2\n");
}
printf("%d\n",cnt);
for(int i=1;i<=cnt;i++)
printf("%d %d\n",ans[i][0],ans[i][1]);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
int t;
scanf("%d",&t);
while(t--)
solve();
return 0;
}

【XSY2785】模型的更多相关文章

  1. ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库

    在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类 ...

  2. ASP.NET Core MVC/WebAPi 模型绑定探索

    前言 相信一直关注我的园友都知道,我写的博文都没有特别枯燥理论性的东西,主要是当每开启一门新的技术之旅时,刚开始就直接去看底层实现原理,第一会感觉索然无味,第二也不明白到底为何要这样做,所以只有当你用 ...

  3. ASP.NET路由模型解析

    大家好,我又来吹牛逼了 ~-_-~ 转载请注明出处:来自吹牛逼之<ASP.NET路由模型解析> 背景:很多人知道Asp.Net中路由怎么用的,却不知道路由模型内部的运行原理,今天我就给大家 ...

  4. 高性能IO模型浅析

    高性能IO模型浅析 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型. (2)同步非阻塞IO(Non-blocking  ...

  5. 探索ASP.NET MVC5系列之~~~4.模型篇---包含模型常用特性和过度提交防御

    其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...

  6. 隐马尔科夫模型python实现简单拼音输入法

    在网上看到一篇关于隐马尔科夫模型的介绍,觉得简直不能再神奇,又在网上找到大神的一篇关于如何用隐马尔可夫模型实现中文拼音输入的博客,无奈大神没给可以运行的代码,只能纯手动网上找到了结巴分词的词库,根据此 ...

  7. webapi - 模型验证

    本次要和大家分享的是webapi的模型验证,讲解的内容可能不单单是做验证,但都是围绕模型来说明的:首先来吐槽下,今天下午老板为自己买了套新办公家具,看起来挺好说明老板有钱,不好的是我们干技术的又成了搬 ...

  8. 谈谈一些有趣的CSS题目(二)-- 从条纹边框的实现谈盒子模型

    开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

  9. 【NLP】蓦然回首:谈谈学习模型的评估系列文章(一)

    统计角度窥视模型概念 作者:白宁超 2016年7月18日17:18:43 摘要:写本文的初衷源于基于HMM模型序列标注的一个实验,实验完成之后,迫切想知道采用的序列标注模型的好坏,有哪些指标可以度量. ...

随机推荐

  1. Python_装饰器进阶_32

    #带参数的装饰器 #500个函数 import time FLAGE = True def timmer_out(flag): def timmer(func): def inner(*args,** ...

  2. H5 26-CSS三大特性之优先级

    26-CSS三大特性之优先级 类>标签>通配符>继承>浏览器默认 --> 0 我是段落 <!DOCTYPE html> <html lang=" ...

  3. java 类与类,类与接口 ,接口与接口关系

    类: 生活中类是人们对客观事物不断认识而产生的抽象概念,而对象则是现实生活中的一个个实体 面向对象程序设计中,对象是程序的基本单位,相似的对象像变量和类型的关系一样归并到一类,所以,并不先具体地定义对 ...

  4. Tea Party CodeForces - 808C (构造+贪心)

    Polycarp invited all his friends to the tea party to celebrate the holiday. He has ncups, one for ea ...

  5. 远程调用HBase出错,尝试10次后,报org.apache.hadoop.hbase.MasterNotRunningException错误

    网上的解决方案挺多的,但都不适用于我今天下午碰到的情况. 环 境:HBase-0.90.3在debian 6下,客户端在windows上.我用之前的HBase服务器是没问题的,但重新解压并配置后就有问 ...

  6. SOAP UI-----测webservice接口

    webservice的请求报文和返回报文都是xml格式的. 使用soapui.storm对webservice接口进行测试,postman无法测. http://www.webxml.com.cn/W ...

  7. JEECG 单点登录 SSO

    jeecg中用户登录的唯一性-CSDN问答https://ask.csdn.net/questions/656639 JEECG 集成KiSSO单点登录实现统一身份认证 - zhangdaiscott ...

  8. VSC软件快捷键

    Shift + Alt + F  格式化 Ctrl+Shift+P, F1显示命令面板 Ctrl+P快速打开,进入File… Ctrl + Shift + N新窗口/实例 Ctrl + Shift + ...

  9. Springboot自定义过滤器Filter

    前言:自己写了个Springboot项目,最近写的功能越来越多,结合业务已经要写过滤器Filter来过滤处理一些请求. 在网上看了几篇博客,总结如下: 过滤器配置方式有两种: 1.通过@WebFilt ...

  10. CLOUD SQL跟踪

    CLOUD会自动在后台执行一些sql语句,所以追踪起来比较麻烦,需要加入一些过滤条件. 比如关键的CLIENTPROCESSID,加入后 ,就能过滤是哪个客户度执行的数据. 过滤数据.