类直径树上贪心

news2024/11/25 14:28:38

http://cplusoj.com/d/senior/p/SS231109C

场上想到枚举点,然后最大值为高,然后可以求最大值。但是感觉计数会重


计数其实不会重,如图中,红色线段显然比蓝色线段优

在这里插入图片描述

所以我们枚举3叉点时没错的

#include<bits/stdc++.h>
using namespace std;
#ifdef LOCAL
 #define debug(...) fprintf(stdout, ##__VA_ARGS__)
#else
 #define debug(...) void(0)
#endif
#define int long long
inline int read(){int x=0,f=1;char ch=getchar(); while(ch<'0'||
ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
#define Z(x) (x)*(x)
#define pb push_back
#define fi first
#define se second
//srand(time(0));
#define N 500010
//#define M
//#define mo
struct node {
	int mx, cnt; 
	void init() { mx=-1e15; cnt=0; }
	node operator +(const node &A) const {
		if(A.mx>mx) return A; 
		if(mx>A.mx) return (*this); 
		return {mx, cnt+A.cnt}; 
	}
	node add() { node A=(*this); A.mx++; return A; }
}ans, f[N]; 
void operator += (node &A, node B) { A=A+B; }
int n, m, i, j, k, T;
int u, v, c[N]; 
vector<int>G[N]; 

void dfs1(int x, int fa) {
	f[x]={0, 1}; 
	for(int y : G[x]) if(y!=fa) {
		dfs1(y, x); f[x]+=f[y].add(); 
	}
	debug("> %lld : %lld %lld\n", x, f[x].mx, f[x].cnt); 
}

void dfs2(int x, int fa, node p) {
	debug("Shang %lld : %lld %lld\n", x, p.mx, p.cnt); 
	int z=G[x].size(), i, j, k=0; 
	vector<node>pre, lst, cao; 
	node dp[3][2], ndp[3][2];
	vector<int>ve; 
	pre.resize(z+2); lst.resize(z+2); ve.resize(z+2); 
	for(auto &t : pre) t.init(); 
	for(auto &t : lst) t.init(); 
	for(auto y : G[x]) if(y!=fa) ve[++k]=y; 
	pre[0]=p; 
	for(i=1; i<=k; ++i) pre[i]=pre[i-1]+f[ve[i]].add(); 
	for(i=k; i>=1; --i) lst[i]=lst[i+1]+f[ve[i]].add(); 
	for(i=1; i<=k; ++i) dfs2(ve[i], x, (pre[i-1]+lst[i+1]).add()); 
	
	if(c[x]<3) return ; 
	int mx=pre[k].mx; 
	debug("[%lld] %lld\n", k, mx); 
	for(i=1; i<=k; ++i) cao.pb(f[ve[i]].add()); cao.pb(p); 
	for(i=0; i<=2; ++i) for(j=0; j<=1; ++j) dp[i][j].init(); 
	dp[0][0]={0, 1}; 
	for(auto t : cao) {
		debug("# %lld %lld\n", t.mx, t.cnt); 
		for(i=0; i<=2; ++i) for(j=0; j<=1; ++j) ndp[i][j].init(); 
		for(i=0; i<=2; ++i) for(j=0; j<=1; ++j) {
			ndp[i][j|(t.mx==mx)]+=dp[i][j]; 
			if(i<2) {
				node cur = {dp[i][j].mx+mx*t.mx, dp[i][j].cnt*t.cnt}; 
				debug("** %lld(%lld %lld) %lld | %lld\n", cur.mx, dp[i][j].mx, mx*t.mx, cur.cnt, j); 
				ndp[i+1][j]+=cur; 
			}
		}
		for(i=0; i<=2; ++i) for(j=0; j<=1; ++j) dp[i][j]=ndp[i][j]; 
	}
	debug("=# %lld %lld\n", dp[2][1].mx, dp[2][1].cnt); 
	ans+=dp[2][1]; 
}

signed main()
{
	freopen("tree.in", "r", stdin);
	freopen("tree.out", "w", stdout);
	#ifdef LOCAL
	  freopen("in.txt", "r", stdin);
	  freopen("out.txt", "w", stdout);
	#endif
//	T=read();
//	while(T--) {
//
//	}	
	n=read(); 
	for(i=1; i<n; ++i) {
		u=read(); v=read(); 
		G[u].pb(v); G[v].pb(u); ++c[u]; ++c[v]; 
		k=max(k, c[u]); k=max(k, c[v]); 
	}
	if(k<=2) return printf("0 1"), 0; 
	node p; p.init(); 
	dfs1(1, 0); 
	dfs2(1, 0, {0, 1}); 
	printf("%lld %lld\n", ans.mx, ans.cnt); 
	return 0;
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1191107.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Terminator终端

Terminator终端 terminator快捷键 sudo apt install terminator使用ctrlaltt开启终端 terminator快捷键 E O W 都是ctrl shift结合 alt方向键&#xff0c;为切换焦点 e分屏失效的解决方案&#xff08;原因是快捷键占有问题&#xff09; ibus-setup将表情符号注释就行了 …

ARMday2(环境创建+工程配置+创建文件+单步调试)

目录 一、汇编环境的创建 二、为工程配置链接脚本&#xff08;map.lds&#xff09; 三、为工程创建汇编文件 start.s 编程调试 接下来我们需要建立一个 start.s 汇编文件添加到我们的工程中去 四、对汇编代码进行单步调试&#xff08;仿真&#xff09; 五、汇编工程的编译 …

遍历List集合和Map进行修改和删除报java.util.ConcurrentModificationException错误详解

一、异常产生 当我们使用foreach迭代一个ArrayList或者HashMap时&#xff0c;如果尝试对集合做一些修改操作&#xff08;例如删除元素或新增&#xff09;&#xff0c;可能会抛出java.util.ConcurrentModificationException的异常。 javapublic static void main(String[] args)…

语音控制:基于ESP8266的DIY助手

随着智能家居的兴起&#xff0c;语音控制成为越来越受欢迎的方式。在本篇文章中&#xff0c;我们将向您介绍如何使用ESP8266构建一个基于语音控制的DIY助手。 第一步&#xff1a;硬件准备 在开始之前&#xff0c;您需要准备一些基础硬件&#xff0c;包括ESP8266模块、麦克风模…

【C++】C++中的IO流

文章目录 一、C语言的输入与输出二、什么是流三、CIO流1.C标准IO流2.C文件IO流 四、stringstream的简单介绍 一、C语言的输入与输出 C语言中我们用到的最频繁的输入输出方式就是scanf ()与printf(): scanf(): 从标准输入设备(键盘)读取数据&#xff0c;并将值存放在变量对应的…

数据结构-图的存储

邻接矩阵法 #define MaxVertexNum 100 //顶点数目的最大值 typedef struct{char Vex[MaxVertexNum]; //顶点表int Edge[MaxVertexNum][MaxVertexNum]; //邻接矩阵&#xff0c;边表int vexnum,arcnum; //图的当前顶点数和边数 }MGraph;无向图 第i个顶点的度第i行&#xff08;或第…

深入理解JVM虚拟机第二十二篇:详解JVM当中与操作数栈相关的字节码指令

大神链接&#xff1a;作者有幸结识技术大神孙哥为好友&#xff0c;获益匪浅。现在把孙哥视频分享给大家。 孙哥链接&#xff1a;孙哥个人主页 作者简介&#xff1a;一个颜值99分&#xff0c;只比孙哥差一点的程序员 本专栏简介&#xff1a;话不多说&#xff0c;让我们一起干翻J…

VUE页面导出PDF方案

1&#xff0c;技术方案为&#xff1a;html2canvas把页面生成canvas图片&#xff0c;再通过jspdf生成PDF文件&#xff1b; 2&#xff0c;安装依赖&#xff1a; npm i html2canvas -S npm i jspdf -S 3&#xff0c;封装导出pdf方法exportPdf.js: // 页面导出为pdf格式 //titl…

简单选择排序(c语言代码实现)

选择排序&#xff1a;简单选择排序&#xff08;不稳定的排序&#xff09; 简单选择排序是一种基础的排序算法&#xff0c;它的基本思路是在未排序的序列中选择最小&#xff08;或最大&#xff09;的元素&#xff0c;将其与序列的第一个元素进行交换&#xff0c;然后在剩余的未…

MySQL-基础篇

文章目录 第一章 MYSQL 概述数据库相关概念MySQL 数据库下载安装启动和停止 MySQL客户端连接解决&#xff1a;mysql 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。配置 Path 环境变量解决&#xff1a;net start mysql80 发生系统错误 5。 拒绝访问。MYSQL 的…

IntelliJ IDEA - Git Commit 后 Commit 窗口不消失解决方案

这个现象是在 2023 年版本后开始的&#xff0c;一开始以为是 Mac 系统的原因&#xff0c;后来发现原来 Windows 也这样&#xff0c;所以应该只跟 IDEA 版本有关 可以看到左侧 commit 后&#xff0c;这个侧边栏还在&#xff0c;按理讲在以前的版本是之前消失&#xff0c;这样使…

layui table合并相同的列

table.render({elem: #samples,url: /index/Develorderss/samplelists?od_idod_id //数据接口,page: { //支持传入 laypage 组件的所有参数&#xff08;某些参数除外&#xff0c;如&#xff1a;jump/elem&#xff09; - 详见文档layout: [prev, page, next, count,skip,limit]…

TCP发送窗口、接收窗口以及其工作原理

1*KvfIrP_Iwq40uVdRZYGnQg.png 上面的图表是从发送方的角度拍摄的快照。我们可以将数据分为4组&#xff1a; 1.已发送并已确认的字节&#xff08;蓝色&#xff09;2.已发送但尚未确认的字节&#xff08;黄色&#xff09;3.未发送但接收方准备好接收的字节&#xff08;绿色&…

【C++】C++静态成员函数,类名直接调用

静态成员函数可以通过类名直接调用&#xff0c;不用创建对象。例如&#xff1a;ClassName::Func();通过类名直接调用因为不用创建对象所以不会运行类的构造方法。适合用于初始化。 参考&#xff1a; C【6】对静态成员函数的用法说明C调用成员函数的几种方法总结C static静态…

大数据毕业设计选题推荐-农作物观测站综合监控平台-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

Linux 多线程编程详解

目录 为什么要使用多线程 线程概念 线程的标识 pthread_t 线程的创建 向线程传入参数 线程的退出与回收 线程主动退出 线程被动退出 线程资源回收(阻塞方式) 线程资源回收(非阻塞方式) 为什么要使用多线程 在编写代码时&#xff0c;是否会遇到以下的场景会感觉到难以…

LINUX入门篇【4】开发篇--开发工具vim的使用

前言&#xff1a; 从这一篇开始&#xff0c;我们将正式进入使用LINUX进行写程序和开发的阶段&#xff0c;可以说&#xff0c;由此开始&#xff0c;我们才开始真正去使用LINUX。 介绍工具&#xff1a; 1.LINUX软件包管理器yum&#xff1a; 1.yum的介绍&#xff1a; 在LINUX…

Swift--量值与基本数据类型

系列文章目录 第一章: Swift–量值与基本数据类型 文章目录 系列文章目录前言对学习过程做一个记录 变量和常量命名规范注释 元祖类型可选类型拆包 typealias 前言 对学习过程做一个记录 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 变量和常量 …

十分钟理解回归测试(Regression Testing)

回归测试是一个系统的质量控制过程&#xff0c;用于验证最近对软件的更改或更新是否无意中引入了新错误或对以前的功能方面产生了负面影响&#xff08;比如你在家中安装了新的空调系统&#xff0c;发现虽然新的空调系统可以按预期工作&#xff0c;但是本来亮的等却不亮了&#…

Leetcode刷题【hot100】盛最多水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff1a;你不能倾斜容器。 示例…