树的合并 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

【提示】

树的直径指的是树上的最长简单路径。

来源

1019


挺好想的题

令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的更多相关文章

  1. 【主席树 启发式合并】bzoj3123: [Sdoi2013]森林

    小细节磕磕碰碰浪费了半个多小时的时间 Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M ...

  2. [CSP-S模拟测试]:模板(ac)(线段树启发式合并)

    题目描述 辣鸡$ljh\ NOI$之后就退役了,然后就滚去学文化课了.他每天都被$katarina$大神虐,仗着自己学过一些姿势就给$katarina$大神出了一道题.有一棵$n$个节点的以$1$号节 ...

  3. POJ 3667 Hotel(线段树 区间合并)

    Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...

  4. HDU 3911 线段树区间合并、异或取反操作

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...

  5. HDU 3911 Black And White(线段树区间合并+lazy操作)

    开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...

  6. 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 ...

  7. HYSBZ 1858 线段树 区间合并

    //Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...

  8. poj3667 线段树 区间合并

    //Accepted 3728 KB 1079 ms //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...

  9. hdu3911 线段树 区间合并

    //Accepted 3911 750MS 9872K //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...

随机推荐

  1. JSPatch - iOS 动态补丁

    JSPatch库,支持在线更新iOS应用,目前BDN项目中有用到,主要用来修复线上Crash和Bug 相关博文推荐: JSPatch – 动态更新iOS APP(这是JSPatch作者的博文) JSP ...

  2. P4746 C’s problem(c)

    时间: 1000ms / 空间: 655360KiB / Java类名: Main 背景 冬令营入学测试 描述 题目描述 小C是一名数学家,由于它自制力比较差,经常通宵研究数学问题. 这次它因为这个数 ...

  3. 用纯CSS实现加载中动画效果

    HTML <div class="pswp__preloader__icn"> <div class="pswp__preloader__cut&quo ...

  4. php v8js

    本文整理自大神 Corz 1.php56 /datas/soft/php56/bin/php -v PHP (cli) #https://blog.csdn.net/lzm198707/article ...

  5. Codeforces Round #460 (Div. 2)-C. Seat Arrangements

    C. Seat Arrangements time limit per test1 second memory limit per test256 megabytes Problem Descript ...

  6. DFS:Tempter of the Bone (规定时间达到规定地点)

    解题心得: 1.注意审题,此题是在规定的时间达到规定的地点,不能早到也不能晚到.并不是最简单的dfs 2.在规定时间达到规定的地点有几个剪枝: 一.公式:所需的步骤 - x相差行 - y相差列 = 偶 ...

  7. Word 2013发布博客测试

    Hello world ! I am from word2013! 测试修改 这里添加一行文字.   参考 1在 Word 中建立博客的相关帮助 2使用Word2013发布随笔到博客园 PS: 参考2 ...

  8. 【Pow(x,n)】

    题目: Implement pow(x, n). 代码: class Solution { public: double myPow(double x, int n) { double ret = S ...

  9. centOS6.6虚拟机启动后登陆界面无法显示

    1.图一和图二对比就很明显发现,我的登陆界面不见了(突然断电导致不正常关机,造成图形界面桌面崩溃) 2.解决方法:启动按Ctrl+Alt+f2切换进命令行界面,root账号进入,重新下载图形界面

  10. 踩坑 Uncaught RangeError: Maximum call stack size exceeded

    今天遇到了一个错误, 堆栈溢出,很好奇就是一个简单ajax请求怎么会报这个错误,研究了一下,发现犯了一个很低级的错误,data的参数错误了: passWord是未定义的变量,值为空,然后导致了这个问题 ...