【CF2021E】Digital Village(All Version)

题目

给你一张 n n n 个点 m m m 条边的无向图,有 p p p 个关键点。你需要选择 k k k 个点染黑,使得这 p p p 个关键点到这 k k k 个黑点的代价和最小。定义代价为两点之间边权最大的边的最小值。
你需要求出 k = 1,2,…,n 的所有答案

E1 n,m,p<=400
E2 n,m,p<=5000
E3 n,m,p<=2e5

传送门

E1 & E2

两点之间最大边权最小值让你想到了什么?最小生成树。
但是这玩意直接在最小生成树上也不好做啊。但是如果是 kruskal 重构树呢?
显然,两个点 ( u , v ) (u,v) (u,v) 之间的代价就是重构树上的 v a l l c a ( u , v ) val_{lca(u,v)} vallca(u,v)
这样我们就可以愉快的dp啦!

d p u , i dp_{u,i} dpu,i 为以 u u u 为根的子树,染黑了 i i i 个关键点的最小代价。
转移要讨论这棵树有没有染黑任何一个点,如果没有的话整棵树的代价就是 s i z × v a l siz\times val siz×val,其中 s i z siz siz 为子树内关键点的个数。
做个树上背包就行啦。时间复杂度 O ( n 2 ) O(n^2) O(n2)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+7,inf=1e18,mod=998244353;
int n,m,k;
vector<bool> bz;
vector<int> val,fa,siz;
vector<vector<int>> e,dp;
int gf(int x)
{return x==fa[x]?x:fa[x]=gf(fa[x]);
}
void dfs(int u,int fa)
{dp[u].assign(1,inf);if(bz[u]){siz[u]=1;dp[u].push_back(0);}for(auto v:e[u]){if(v==fa) continue;dfs(v,u);vector<int> dpn(siz[u]+siz[v]+1,inf);for(int i=1; i<=siz[u]+siz[v]; i++){for(int j=max(0ll,i-siz[u]); j<=min(i,siz[v]); j++){if(j==0){dpn[i]=min(dpn[i],dp[u][i-j]+val[u]*siz[v]);}else if(i==j){dpn[i]=min(dpn[i],dp[v][j]+val[u]*siz[u]);}else{dpn[i]=min(dpn[i],dp[u][i-j]+dp[v][j]);}}}siz[u]+=siz[v];dp[u]=dpn;}
}
void O_o()
{cin>>n>>m>>k;bz.assign(2*n,0);for(int i=1; i<=k; i++){int x;cin>>x;bz[x]=1;}vector<array<int,3>> edge;//l,x,yfor(int i=1; i<=m; i++){int x,y,l;cin>>x>>y>>l;edge.push_back({l,x,y});}sort(edge.begin(),edge.end());fa.assign(2*n,0);for(int i=1; i<=2*n; i++) fa[i]=i;int rt=n;e.assign(2*n,vector<int>());val.assign(2*n,0);for(auto [l,x,y]:edge){int u=gf(x),v=gf(y);if(u==v) continue;rt++;fa[u]=rt;fa[v]=rt;val[rt]=l;e[rt].push_back(u);e[rt].push_back(v);}dp.assign(2*n,vector<int>());siz.assign(2*n,0);dfs(rt,0);for(int i=1; i<=min(k,n); i++)cout<<dp[rt][i]<<" ";for(int i=k+1; i<=n; i++)cout<<"0 ";cout<<"\n";
}
signed main()
{ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);cout<<fixed<<setprecision(12);int T=1;cin>>T;while(T--){O_o();}
}

这个树上背包似乎很难继续优化了呢。我们必须从题目更深的性质去思考问题。
在解决 E3 之前,我们不妨先看一下这道题:

CCPC2024 山东邀请赛 F

在这里插入图片描述
这是一道签到题。
可以发现,这个式子可以拆成 k k k 段后缀和之和,并且其中一段后缀和必须是整个序列。
所以直接把后缀和排个序,选出前 k − 1 k-1 k1 大的后缀和,再加上整个序列的和即可。

E3

在题目中,一个点都不染色是不合法的,代价应该为 i n f inf inf,但这不利于我们解题。
我们不妨假设他们每一条路径都经过了最大的那条边,也就是初始答案 a n s = s i z r t ∗ v a l r t ans=siz_{rt}*val_{rt} ans=sizrtvalrt
把样例的重构树画出来,观察一下染黑了一个叶子,对答案会有什么影响?
不太好看出来?由那道签到题的启发,给 v a l val val 做个树上差分试试?
可以发现,从叶子结点到根的那条路径上, v a l f a − v a l u val_{fa}-val_{u} valfavalu 的计算次数都被减少了 s i z u siz_u sizu
再染一个点试试?可以发现,从叶子结点,一直到已经被选择过的那条链为止, v a l f a − v a l u val_{fa}-val_{u} valfavalu 的计算次数都被减少了 s i z u siz_u sizu
问题就转换成了,你要在树上选出减少答案前 k k k 大,互不相交的链。
是不是很像树链剖分?
没错,我们把 ( v a l f a − v a l u ) ∗ s i z u (val_{fa}-val_{u})*siz_u (valfavalu)sizu 作为 ( u , f a u ) (u,fa_u) (u,fau) 的边权,对整棵树做长链剖分(jiangly:这是典中典长链剖分题)。
把所有的长链的权值排序,然后每次选出前 k k k 大减去就做完啦!

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+7,inf=1e18,mod=998244353;
int n,m,k;
vector<bool> bz;
vector<int> val,fa,siz,p;
vector<vector<int>> e;
int gf(int x)
{return x==fa[x]?x:fa[x]=gf(fa[x]);
}
int dfs(int u,int fa)
{if(bz[u]){siz[u]=1;}int mx=0;for(auto v:e[u]){int res=dfs(v,u);siz[u]+=siz[v];if(mx<res)swap(res,mx);p.push_back(res);}if(fa!=0)mx+=siz[u]*(val[fa]-val[u]);return mx;
}
void O_o()
{cin>>n>>m>>k;bz.assign(2*n,0);for(int i=1; i<=k; i++){int x;cin>>x;bz[x]=1;}vector<array<int,3>> edge;//l,x,yfor(int i=1; i<=m; i++){int x,y,l;cin>>x>>y>>l;edge.push_back({l,x,y});}sort(edge.begin(),edge.end());fa.assign(2*n,0);for(int i=1; i<=2*n; i++) fa[i]=i;int rt=n;e.assign(2*n,vector<int>());val.assign(2*n,0);for(auto [l,x,y]:edge){int u=gf(x),v=gf(y);if(u==v) continue;rt++;fa[u]=rt;fa[v]=rt;val[rt]=l;e[rt].push_back(u);e[rt].push_back(v);}siz.assign(2*n,0);p.clear();p.push_back(dfs(rt,0));int ans=k*val[rt];sort(p.begin(),p.end(),greater<>());for(int i=0; i<n; i++){ans-=p[i];cout<<ans<<" ";}cout<<"\n";
}
signed main()
{ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);cout<<fixed<<setprecision(12);int T=1;cin>>T;while(T--){O_o();}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mapsui绘制WKT的示例

步骤 创建.NET Framework4.8的WPF应用在NuGet中安装Mapsui.Wpf 4.1.7添加命名空间和组件 <Window x:Class"TestMapsui.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winf…

Python物联网编程:10个IoT设备通信的脚本

今天我们要聊的是如何使用Python编写脚本来实现10个IoT设备之间的通信。物联网&#xff08;IoT&#xff09;是一个充满无限可能的领域&#xff0c;它将日常设备连接到互联网&#xff0c;使它们能够互相通信、收集数据并做出响应。Python以其简洁易懂的语法和强大的库支持&#…

浅谈 WMS 的应用行业_SunWMS智慧仓储物流系统

【大家好&#xff0c;我是唐Sun&#xff0c;唐Sun的唐&#xff0c;唐Sun的Sun。一站式数智工厂解决方案服务商】 仓库管理系统&#xff08;WMS&#xff09;已经成为众多行业优化运营、提高效率和竞争力的重要工具。WMS 的应用范围广泛&#xff0c;涵盖了制造业、零售业、电商、…

调用第三方接口

目录 一、分析给出的接口文档 二、请求体格式之间的区别 三、示例代码 一、分析给出的接口文档 一般的接口文档包括以下几大部分&#xff1a; 1、请求URL&#xff1a;http://{ip}:{port}/api/ec/dev/message/sendCustomMessageSingle 2、请求方式&#xff1a;POST、GET等 3、…

基于SpringBoot+Vue的超市管理系统设计实现(协同过滤算法、图形化分析)

&#x1f388;系统亮点&#xff1a;协同过滤算法、图形化分析&#xff1b; 一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk17 前端&#xff1a; 技术&#xff1a;框…

主数据驱动的数据治理高清书籍领取

主数据驱动的数据治理 原理、技术与实践 高清版本电子书领取 绝对高清版本的电子书&#xff0c;抓紧来获取吧&#xff5e;&#xff5e;&#xff5e;

【宽字节注入】

字符编码 url 编码 GBK编码 utf8 编码 宽字节注入 php中的转译函数 宽字节注入介绍 练习 正常输入没有回显&#xff1a; 没有回显 usernameadmin&passwordadmin 闭合单引号&#xff0c;依旧没有回显 usernameadmin and 11%23&passwordadmin利用宽字节尝试闭合,依旧…

DIFY上使用多种大语言模型(MindCraft API)

注册MindCraft并创建API KEY 首先我们在智匠MindCraft上注册账号并创建API KEY&#xff0c;参考接口调用文档&#xff0c;查看我们能调用哪些模型。我们可以看到这个开发平台上整合了主流的大语言模型&#xff0c;并且是兼容openai接口的。 进入DIFY的设置界面 然后我们在DIFY上…

ArcGIS属性表怎么连接Excel表格?

ArcGIS中&#xff0c;属性表是存储空间要素非几何特征属性的重要工具。有时&#xff0c;我们需要将这些属性与外部数据&#xff0c;如Excel表格中的数据进行连接。以下是如何在ArcGIS中实现这一过程的步骤。 要把Excel表里的数据导入到ArcGIS里的地图数据里面&#xff0c;对数…

C语言 | Leetcode C语言题解之第463题岛屿的周长

题目&#xff1a; 题解&#xff1a; const int dx[4] {0, 1, 0, -1}; const int dy[4] {1, 0, -1, 0};int dfs(int x, int y, int** grid, int n, int m) {if (x < 0 || x > n || y < 0 || y > m || grid[x][y] 0) {return 1;}if (grid[x][y] 2) {return 0;}g…

统信服务安装mysql8.4版本,二进制文件

一&#xff1a;建立MySQL用户和用户组 sudo groupadd mysql sudo useradd -r -g mysql -s /bin/false mysql 二&#xff1a;下载MySQL安装包 MySQL :: Download MySQL Community Server (Archived Versions) 找对应的版本 三&#xff1a;解压二进制安装包&#xff0c;从命…

【Linux复习】指令

文章目录 1.>2. cat3.系统命令bash和shell和kernel权限只被认证一次粘滞位引入前提知识场景解释为什么普通用户&#xff08;无w权限&#xff09;可以删除文件&#xff1f;为什么普通用户通过sudo设置文件权限为000后仍能删除文件&#xff1f; 结论 粘滞位是干什么的&#xf…

8款宝藏手机app,适配安卓和苹果手机

好用的手机APP太多&#xff0c;差点挑花了眼&#xff01;今天来分享4款苹果手机和4款安卓手机上的宝藏软件&#xff0c;看看你喜欢哪一款~ IOS系统APP 1.搜图神器 一款拥有海量图片资源的图片搜索神器&#xff0c;它聚合海内外知名搜索引擎&#xff0c;想要图片直接搜索就行…

Vue3 响应式数据

ref 基本数据类型响应式 语法&#xff1a;let xxx ref(初始值)。**返回值&#xff1a;**一个RefImpl的实例对象&#xff0c;简称ref对象或ref&#xff0c;ref对象的value属性是响应式的。注意点&#xff1a; TS中操作数据需要&#xff1a;xxx.value&#xff0c;但模板中不需要…

第三届“讯方杯”大赛常见问题解答

9月20日&#xff0c;第三届“讯方杯”全国大学生信息技术应用及创新大赛正式拉开帷幕。自大赛报名启动以来&#xff0c;全国各大高校热烈响应、广泛参与。为了更好地服务于各参赛团队&#xff0c;大赛组委会针对收集到的各类常见问题&#xff0c;整理了热点问答集锦&#xff0c…

大型公共建筑用电管理集中监测平台功能介绍

在当国家对能源管理和环境保护日益重视的背景下&#xff0c;相关政策不断出台&#xff0c;推动企业用能向智能化管理、数字化管理方向转型。电能因为方便传输、易于转换、便于控制等特性&#xff0c;成为广大企事业单位生产、办公主要的能量来源。双碳背景下&#xff0c;由于电…

动态内存管理练习题的反汇编代码分析(底层)

目录 1.练习题回顾 2.反汇编代码 3.分析 lea指令的作用 1.给普通指针赋值 反汇编显示 2.给结构体指针赋值 反汇编显示 mov 指令的作用 1.取普通指针指向地址的值(等价为C语言的*) 反汇编显示 2.取结构体指针指向地址里的值 反汇编显示 3.总结->的作用 4.回到…

回归预测 | Matlab基于SABO-SVR减法平均算法优化支持向量机的数据多输入单输出回归预测

回归预测 | Matlab基于SABO-SVR减法平均算法优化支持向量机的数据多输入单输出回归预测 目录 回归预测 | Matlab基于SABO-SVR减法平均算法优化支持向量机的数据多输入单输出回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab基于SABO-SVR减法平均算法优化…

Robust多模态模型的开发

本文所涉及所有资源均在 传知代码平台 可获取。 目录 Robust 多模态模型&#xff1a;寻找遗失的模态&#xff01; 一、研究背景 二、模型结构和代码 三、数据集介绍 六、性能展示 六、实现过程 七、运行过程 Robust 多模态模型&#xff1a;寻找遗失的模态&#xff01; 近年来&a…

最新项目全功能知识付费小程序源码系统 带完整的安装代码包以及搭建部署教程

系统概述 知识付费小程序源码系统是一款基于先进技术架构设计的综合性平台。它旨在为用户提供一站式的知识付费解决方案&#xff0c;涵盖了从内容创作到用户管理的各个环节。 该系统采用了现代化的开发理念和技术手段&#xff0c;确保了系统的稳定性、安全性和高效性。它具有…