树的合并 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 < ...
随机推荐
- java基础面试题:抽象类中是否可以有静态的main方法?
- Dynemic Web Project中使用servlet的 doGet()方法接收来自浏览器客户端发送的add学生信息形成json字符串输出到浏览器并保存到本地磁盘文件
package com.swift.servlet; import java.io.FileOutputStream;import java.io.IOException;import java.io ...
- 在React中使用Redux数据流
问题:数据流是什么呢?为什么要用数据流? 答案:1.数据流是我们的行为与相应的抽象 2.使用数据流帮助我们明确了行为的对应的响应 问题: React与数据流的关系 1.React是纯 V 层的前端框架 ...
- 2019 ACM-ICPC全国邀请赛(西安) M.Travel 二分+判联通
https://nanti.jisuanke.com/t/39280 讲道理这题写bfs求最大边权限制下从1到n的最短步数,然后二分判一下就行了. 然鹅我还是直接套了dij,一开始纠结dij能不能过, ...
- EasyUI取消树节点选中
$('#organTree').find('.tree-node-selected').removeClass('tree-node-selected'); 取消树的节点选中
- SSH密钥验证
基于密钥验证 1. 在客户端生成密钥对 可以先进入用户的.ssh 目录 cd ~/.ssh ssh-keygen -t rsa [-P '' ] [-f "~/.ssh/id_rsa&quo ...
- LeetCode955删列造序 ||
问题:删列造序 || 给定由 N 个小写字母字符串组成的数组 A,其中每个字符串长度相等. 选取一个删除索引序列,对于 A 中的每个字符串,删除对应每个索引处的字符. 比如,有 A = [" ...
- API Star:一个 Python 3 的 API 框架
为了在 Python 中快速构建 API,我主要依赖于 Flask.最近我遇到了一个名为 "API Star" 的基于 Python 3 的新 API 框架.由于几个原因,我对它很 ...
- python3 提成计算
题目 企业发放的奖金根据利润提成. 利润(I)低于或等于10万元时,奖金可提10%: 利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%: 20万到4 ...
- 2019腾讯暑期实习面试(offer)前端
最近在忙着准备找实习,所以没有更新之前的文章. 不过所幸功夫不负有心人,我拿到了腾讯的offer. 这里分享一下面试的经验. 简介 本人双非本科,普通学生一枚. 面的是腾讯的Web前端开发. 整个面试 ...