树的合并 connect
树的合并 connect
题目描述
话说moreD经过不懈努力,终于背完了循环整数,也终于完成了他的蛋糕大餐。
但是不幸的是,moreD得到了诅咒,受到诅咒的原因至今无人知晓。
moreD在发觉自己得到诅咒之后,决定去寻找闻名遐迩的术士CD帮忙。
话说CD最近在搞OI,遇到了一道有趣的题目:
给定两棵树,则总共有N*M种方案把这两棵树通过加一条边连成一棵树,那这N*M棵树的直径大小之和是多少呢?
CD为了考验moreD是否值得自己费心力为他除去诅咒,于是要他编程回答这个问题,但是这moreD早就被诅咒搞晕了头脑,就只好请你帮助他了。
输入
第一行两个正整数N,M,分别表示两棵树的大小。
接下来N-1行,每行两个正整数ai,bi,表示第一棵树上的边。
接下来M-1行,每行两个正整数ci,di,表示第二棵树上的边。
输出
一行一个整数,表示答案。
样例输入
4 3
1 2
2 3
2 4
1 3
2 3
样例输出
53
提示
【数据范围】
对于20%的数据满足N<=300,M<=300
对于50%的数据满足N,M<=3000
对于100%的数据满足N<=10^5,M<=10^5,1<=ai,bi<=N,1<=ci,di<=M
【提示】
树的直径指的是树上的最长简单路径。
来源
挺好想的题
令a[i]表示i开头第一棵树上最长链
b[i]表示i开头第二棵树上最长链
Max为两棵树直径的max
对于a[i]和b[j]
贡献为max(Max,a[i]+b[j]+1)
拿个指针扫扫就行了
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 100005
using namespace std;
int n,m,tot,head[maxn],f[maxn],g[maxn],dp[maxn],t1,t2;
long long a[maxn],b[maxn],sum[maxn],ans,ma;
struct node{
int v,nex;
}e[maxn*2];
void lj(int t1,int t2){
tot++;e[tot].v=t2;e[tot].nex=head[t1];head[t1]=tot;
}
void dfs1(int k,int fa){
int Max=-1e9,max2=-1e9;
for(int i=head[k];i;i=e[i].nex){
if(e[i].v!=fa){
dfs1(e[i].v,k);
if(f[e[i].v]>Max){
max2=max(max2,Max);
Max=f[e[i].v];
}
else max2=max(max2,f[e[i].v]);
}
}
if(Max==-1e9)f[k]=0,g[k]=-1e9;
else {f[k]=Max+1;g[k]=max2+1;}
//cout<<k<<' '<<f[k]<<' '<<g[k]<<endl;
}
void dfs2(int k,int fa){
for(int i=head[k];i;i=e[i].nex){
if(e[i].v!=fa){
dp[e[i].v]=max(dp[e[i].v],dp[k]+1);
if(f[e[i].v]==f[k]-1){
dp[e[i].v]=max(dp[e[i].v],g[k]+1);
}
else dp[e[i].v]=max(dp[e[i].v],f[k]+1);
dfs2(e[i].v,k);
}
}
}
void Q(){
for(int i=1;i<=n;i++)head[i]=f[i]=g[i]=dp[i]=0;
tot=0;
}
int main()
{
cin>>n>>m;
for(int i=1;i<n;i++){
scanf("%d%d",&t1,&t2);
lj(t1,t2);lj(t2,t1);
}
dfs1(1,0);dfs2(1,0);
for(int i=1;i<=n;i++)a[i]=max(f[i],dp[i]);
Q();
for(int i=1;i<m;i++){
scanf("%d%d",&t1,&t2);
lj(t1,t2);lj(t2,t1);
}
dfs1(1,0);dfs2(1,0);
for(int i=1;i<=m;i++){
b[i]=max(f[i],dp[i]);
}
sort(a+1,a+n+1);sort(b+1,b+m+1);
for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
ma=max(a[n],b[m]);
int l=1;
for(int i=m;i>=1;i--){
while(b[i]+a[l]+1<ma&&l<=n)l++;
long long num=n-l+1;
long long tmp=b[i]*num;tmp+=sum[n]-sum[l-1];tmp+=num;
tmp+=ma*(n-num);
ans+=tmp;
}
cout<<ans<<endl;
return 0;
}
树的合并 connect的更多相关文章
- 【主席树 启发式合并】bzoj3123: [Sdoi2013]森林
小细节磕磕碰碰浪费了半个多小时的时间 Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M ...
- [CSP-S模拟测试]:模板(ac)(线段树启发式合并)
题目描述 辣鸡$ljh\ NOI$之后就退役了,然后就滚去学文化课了.他每天都被$katarina$大神虐,仗着自己学过一些姿势就给$katarina$大神出了一道题.有一棵$n$个节点的以$1$号节 ...
- POJ 3667 Hotel(线段树 区间合并)
Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...
- HDU 3911 线段树区间合并、异或取反操作
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...
- HDU 3911 Black And White(线段树区间合并+lazy操作)
开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...
- SPOJ COT3 Combat on a tree(Trie树、线段树的合并)
题目链接:http://www.spoj.com/problems/COT3/ Alice and Bob are playing a game on a tree of n nodes.Each n ...
- HYSBZ 1858 线段树 区间合并
//Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...
- poj3667 线段树 区间合并
//Accepted 3728 KB 1079 ms //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...
- hdu3911 线段树 区间合并
//Accepted 3911 750MS 9872K //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...
随机推荐
- github不能加载css、js解决办法
很奇怪,上午在公司还能正常访问github,晚点访问却有问题,页面样式明显错乱. 在FireFox下用F12开发者工具一看,有2条css和2条js 404 了,猜想应该是github的DNS被GFW污 ...
- 阿里云服务器下安装LAMP环境(CentOS Linux 6.3) 安装与配置 php
下面我们一起为服务器安装 PHP,在使用 yum 安装软件包的时候,yum 会去默认的资源库里查看我们要安装的软件包,然后到指定的服务器上下载并安装. 但是有的时候,我们要安装的软件包并没有包含在默认 ...
- Oracle 自动生成hive建表语句
从 oracle 数据库导数到到 hive 大数据平台,需要按照大数据平台的数据规范,重新生成建表的 SQL 语句,方便其间,写了一个自动生成SQL的存储过程. ① 创建一张表,用来存储源表的结构,以 ...
- 稍微深入点理解C++复制控制【转】
通过一个实例稍微深入理解C++复制控制过程,参考资料<C++ primer>,介绍点基本知识: 1.在C++中类通过特殊的成员函数:复制构造函数.赋值操作符和析构函数来控制复制.赋值和撤销 ...
- grep与正则表达式使用
grep简介 grep 是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来.通常grep有三种版本grep.egrep(等同于grep -E)和fgrep.egrep为扩展的g ...
- 六、Shell echo命令
Shell echo命令 Shell 的 echo 指令与 PHP 的 echo 指令类似,都是用于字符串的输出.命令格式: echo string 您可以使用echo实现更复杂的输出格式控制. 1. ...
- NopCommerce(Core)学习目录
1.NopCommerce下载运行 2.登录及权限 3.日志 4.依赖注入使用autofac 5.插件实现 ...
- 如何使用koa实现socket.io官网的例子
socket.io官网中使用express实现了一个最简单的IM即时聊天,今天我们使用koa来实现一下 ### 框架准备 确保你本地已经安装好了nodejs和npm,使用koa要求node版本> ...
- 【JS】JS实现时间戳转换成普通时间
var time = 1514457627; alert(getDate(time)); function getDate(tm){ var tt=new Date(parseInt(tm) * 10 ...
- STM32启动文件:startup_stm32f10x_hd.s等启动文件的简单描述
在官方的库文件中,分别有如下文件: startup │ │ │ ├─arm │ │ │ │ startup_stm32f10x_cl.s │ │ │ │ startup_stm32f10x_hd.s ...