首页 > 其他分享 >[POI2011] INS-Inspection

[POI2011] INS-Inspection

时间:2024-01-13 22:37:31浏览次数:23  
标签:sz maxx 重心 int POI2011 INS fa son Inspection

分析

看到标签里写的 dp,想了想可能是换根,但我不会,怎么办呢?

考虑什么时候会是 \(-1\)。观察样例发现,只有行动中心为 \(2\) 的时候才不是 \(-1\),而 \(2\) 恰好是树的重心,那么猜想只有重心才不是 \(-1\),接下来证明它。

如果一个点不是重心,那么说明至少存在其中一个子树 \(T'\) 大小大于 \(\frac{n}{2}\),那么剩下的子树大小之和一定小于 \(\frac{n}{2}-1\),则我们每次访问完 \(T'\) 中的一个节点后,要保证相邻两次不走重复道路,就需要访问一个 \(T'\) 外的节点,如此到最后,会发现除了 \(T'\) 中的 \(2\) 个点以外其它点都访问完了,这时但凡再去访问一个点,剩下那个点就访问不到了,因此不是重心的点都是 \(-1\)。

做到这一步了,下一步就开始想对于重心应该输出什么。这时候,如果恰有子树 \(T'\) 的节点树为 \(\frac{n}{2}\),那么我们必须先访问 \(T'\) 中的一个点,否则就会最后剩下 \(2\) 个 \(T'\) 中的点没访问,又无解了。既然需要先访问 \(T'\) 中的点,那么最后必定也会剩下 \(T'\) 中的点,我们想让最后这条路径尽量长(否则它要被计算两次),所以就选择 \(T'\) 中深度最大的点。综上,如果重心 \(c\) 存在一个子树 \(T'\) 的节点个数为 \(\frac{n}{2}\),答案为 \(2\times\displaystyle\sum_x\operatorname{dist}(c,x)-\max_x(\operatorname{dist(c,x)}\times\{x\in T'\})\),其中 \(\operatorname{dist}(i,j)\) 表示 \(i,j\) 的距离,\(\{x\in T'\}\) 表示 \(\begin{cases} 1 &\text{if } x\in T' \\ 0 &\text{if } x\not \in T' \end{cases}\)。

如果不存在这样的子树 \(T'\),那么对选择没有要求,又因为 \(c\) 是重心,必然存在合法解,那么最优肯定是选择深度最大的结尾,因此此时答案为 \(2\times\displaystyle\sum_x\operatorname{dist}(c,x)-\max_x(\operatorname{dist(c,x)})\)。

由于重心最多 \(2\) 个,所以复杂度 \(O(n)\)。

AC Code

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int maxx[N],is[N],sz[N],n,dep[N],rt,son[N],tag[N];
vector<int> G[N];
void dfs(int u,int fa)
{
	sz[u]=1;
	maxx[u]=0;
	for(auto v:G[u])
	{
		if(v==fa) continue;
		dfs(v,u);
		sz[u]+=sz[v];
		maxx[u]=max(maxx[u],sz[v]);
		if(maxx[u]==n/2&&!son[u]) son[u]=v;
	}
	maxx[u]=max(maxx[u],n-sz[u]);
	if(maxx[u]==n/2&&!son[u]) son[u]=fa;
	if(maxx[u]<=(n>>1)) is[u]=1;
}
void dfs2(int u,int fa)
{
	tag[u]=(u==son[rt])|tag[fa];
	if(fa==rt) dep[u]=1;
	for(auto v:G[u])
	{
		if(v==fa) continue;
		dep[v]=dep[u]+1;
		dfs2(v,u);
	}
}
int main()
{
	cin>>n;
	for(int i=1;i<n;i++)
	{
		int u,v;
		cin>>u>>v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++)
	{
		if(!is[i]) cout<<-1<<endl;
		else
		{
			memset(dep,0,sizeof dep);
			memset(tag,0,sizeof tag);
			rt=i;
			dfs2(i,0);
			int ans=0,maxd=0;
			for(int i=1;i<=n;i++) ans+=dep[i];
			if(!son[i])
			for(int i=1;i<=n;i++) maxd=max(maxd,dep[i]);
			else
			for(int i=1;i<=n;i++) maxd=max(maxd,dep[i]*tag[i]);
			cout<<ans*2-maxd<<endl;
		}
	}
	return 0;
}

标签:sz,maxx,重心,int,POI2011,INS,fa,son,Inspection
From: https://www.cnblogs.com/Crazyouth/p/17963118

相关文章

  • instanceof 和类型转换
    注意点父类引用指向子类的对象把子类转换为父类,向上转型;把父类转换为子类,向下转型;强制转换方便方法的调用,减少重复的代码!简洁封装、继承、多态!抽象类,接口快捷键补充语句  举例转换类型之后使用方法 输出结果 这样改写,输出结果一样 代码//J......
  • https://mp.weixin.qq.com/s/dBVwoInshAv3wMxkx9Sfvw
    优秀的Verilog/FPGA开源项目介绍(三十一)-OFDM(qq.com)OFDM介绍在电信领域,正交频分复用技术(OFDM-orthogonalfrequency-divisionmultiplexing)是一种数字传输类型,在多个载波频率上对数字数据进行编码的方法。OFDM已发展成为一种流行的数字通信方案,用于数字电视和音频广......
  • 安装npm install报错npm ERR! code ETIMEDOUT npm ERR! errno ETIMEDOUT npm ERR! net
    执行命令:npmrundev启动前端项目报如下错误,vue-cli-service是Vue一个启动的插件,需要安装D:\nodejs\npm.cmdrundev>[email protected]>vue-cli-serviceserve--open'vue-cli-service'不是内部或外部命令,也不是可运行的程序或批处理文件。Processfinishedwithe......
  • 【flink番外篇】9、Flink Table API 支持的操作示例(10)- 表的OrderBy、Offset 和 Fetch
    文章目录Flink系列文章一、maven依赖二、表的OrderBy,Offset和Fetch操作三、表的insert操作本文介绍了表的OrderBy、Offset和Fetch、insert操作,以示例形式展示每个操作的结果。本文除了maven依赖外,没有其他依赖。一、maven依赖本文maven依赖参考文章:【flink番外篇】9、Flin......
  • 内部的,内在的   inner, inside, interior, internal, inward
    inside  a.里面的,内部的;internal  a.内部的,体内的;国内的,内政的;inner  a.内部的,靠近中心的;内心的,内在的;interior  a.内部的;内陆的;国内的,内政的。 内部的,内在的inner,inside,interior,internal,inward这些形容词均含“内部的,内在的”之意。inner:......
  • Jenkins邮件模板
    模板一:1<!DOCTYPEhtml>2<html>3<head>4<metacharset="UTF-8">5<title>${ENV,var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title>6</head>78<bodyleftmargin="8"marginw......
  • 配置jenkins利用gitlab webhook提交自动触发打包
    1、jenkins安装gitlab插件2、gitlab对应的项目生成访问令牌3、jenkins配置api_token此处的api_token就是刚才gitlab生成的访问令牌4、jenkins项目上配置webhook点击“高级”展开拉到最底下生成项目token5、gitlab配置webhook进入gitlab项目的设置--webhook输入je......
  • Jenkins简介及安装配置详解:开启持续集成之旅
    Jenkins简介及安装配置详解:开启持续集成之旅一、Jenkins介绍Jenkins是一个开源的、用Java编写的持续集成和持续交付(CI/CD)工具。它提供了一种简单易用的方式来自动化构建、测试和部署软件。Jenkins的主要目标是帮助开发团队加快软件开发过程,提高软件质量,并通过自动化流程减......
  • Docker + Jenkins 如何实现自动化部署?
    Docker+Jenkins如何实现自动化部署?一.概述实验室每次项目发布测试时,都要手动本地打包好了然后上传到服务器,替换原来nginx下面的目录文件,十分麻烦和繁琐。这次就来优化一下,通过Dockerfile+Jenkins实现自动化部署二.实践Nginx相关安装nginx一定要按照官方的......
  • MySql 中 INSTR() 用法
    在MySQL中,INSTR()函数用于查找一个字符串中是否包含另一个指定的子串,并返回该子串在原始字符串中第一次出现的位置。以下是INSTR()函数的语法:INSTR(str,substr)其中,str是要搜索的目标字符串;substr是要查找的子字符串。如果str包含substr,则返回substr在str中第一......