设f[i][0/1/2/3/4/5]表示i子树中选一条链不包含根/i子树中选一条链包含根但不能继续向上延伸/i子树中选一条链可以继续向上延伸/选两条链不包含根/选两条链包含根但不能继续向上延伸/选两条链能继续向上延伸,大力讨论即可。代码看起来很(mo)有(ming)意(qi)思(miao)。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 500010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int T,n,p[N],f[N][],t;
int mx[][];
struct data{int to,nxt;
}edge[N<<];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
inline void up(int &x,int y){x=max(x,y);}
inline int max(int x,int y,int z){return max(max(x,y),z);}
void update(int x)
{
for (int i=;i<;i++)
for (int j=;j<;j++)
if (f[x][i]>f[mx[j][i]][i])
{
for (int k=;k>j;k--) mx[k][i]=mx[k-][i];
mx[j][i]=x;break;
}
}
int findmx(int x){return f[mx[][x]][x];}
int findmx(int x,int y)
{
if (mx[][x]!=mx[][y]) return f[mx[][x]][x]+f[mx[][y]][y];
return max(f[mx[][x]][x]+f[mx[][y]][y],f[mx[][x]][x]+f[mx[][y]][y]);
}
int findmx(int x,int y,int z)
{
int s=-n;
for (int i=;i<;i++)
for (int j=i+;j<;j++)
for (int k=;k<;k++)
if (mx[k][z]!=mx[i][x]&&mx[k][z]!=mx[j][y]) up(s,f[mx[k][z]][z]+f[mx[i][x]][x]+f[mx[j][y]][y]);
return s;
}
int findmx(int a,int b,int c,int d){return f[mx[][a]][a]+f[mx[][b]][b]+f[mx[][c]][c]+f[mx[][d]][d];}
void dfs(int k,int from)
{
int son=;
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=from) son++,dfs(edge[i].to,k);
memset(mx,,sizeof(mx));
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=from) update(edge[i].to);
f[k][]=max(findmx(),findmx()+,findmx()+);
f[k][]=findmx(,)+son-;
f[k][]=max(son,findmx()+son-);
f[k][]=max(findmx(),findmx()+,findmx()+);
for (int i=;i<;i++)
for (int j=i;j<;j++)
up(f[k][],findmx(i,j)+-(i==)-(j==));
f[k][]=max(findmx(,,,)-,max(findmx(,,)-,findmx(,,)-),findmx(,)-)+son;
f[k][]=max(max(findmx()-,findmx(,,)-,max(findmx(,),findmx(,),findmx(,))-),max(findmx(),findmx(),findmx())-)+son;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4871.in","r",stdin);
freopen("bzoj4871.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
T=read();int op=read();
while (T--)
{
n=read();if (op>=) read(),read();if (op==) read(),read();
t=;for (int i=;i<=n;i++) p[i]=;
f[][]=f[][]=f[][]=f[][]=f[][]=f[][]=-n;
for (int i=;i<n;i++)
{
int x=read(),y=read();
addedge(x,y),addedge(y,x);
}
dfs(,);
printf("%d\n",max(max(f[][],f[][],f[][]),max(f[][],f[][],f[][])));
}
return ;
}

最新文章

  1. es6学习笔记(1) let和const命令详解
  2. Python全栈开发【面向对象进阶】
  3. 按要求编写Java应用程序。 (1)创建一个叫做People的类: 属性:姓名、年龄、性别、身高 行为:说话、计算加法、改名 编写能为所有属性赋值的构造方法; (2)创建主类: 创建一个对象:名叫“张三”,性别“男”,年龄18岁,身高1.80; 让该对象调用成员方法: 说出“你好!” 计算23+45的值 将名字改为“李四”
  4. Cocos2d-x 3.2 学习笔记(十六)保卫萝卜 游戏主循环与定时器
  5. GLM in SPM
  6. iOS开发小技巧--字典和数组的中文输出
  7. tcp 重发 应用层重传
  8. 【笔记】WPF实现ViewPager引导界面效果及问题汇总
  9. random.sample
  10. android 7.0带来的
  11. HTML5 标准属性 NEW:HTML 5 中新的标准属性。 注释:HTML 4.01 不再支持 accesskey 属性:
  12. Jmeter测试HTTPS接口
  13. JMS 基础
  14. Codeforces Round #449 (Div. 2) D. Ithea Plays With Chtholly
  15. Android 网络编程之最新OKHTTP:3.9.0
  16. Backup and Recovery Types
  17. web开发中的跨域整理
  18. [LeetCode系列] 双单链表共同节点搜索问题
  19. Beta冲刺第二周王者荣耀交流协会第五次会议
  20. 【刷题】BZOJ 1468 Tree

热门文章

  1. 成都Uber优步司机奖励政策(2月23日)
  2. 【LG2495】[SDOI2011]消耗战
  3. 使用Python访问HDFS
  4. hdu1010Tempter of the Bone(迷宫dfs+剪枝)
  5. 第六阶段&#183;数据库MySQL及NoSQL实践第1章&#183;章节一MySQL数据库
  6. python里pickle模块
  7. Micro:bit 硬件架构介绍
  8. (Pyhton爬虫03)爬虫初识
  9. 158. Valid Anagram【LintCode by java】
  10. 洪水!(Flooded! ACM/ICPC World Final 1999,UVa815)