2023NOIP A层联测14 修路

2023-10-19 21:04
文章标签 14 联测 2023noip 修路

本文主要是介绍2023NOIP A层联测14 修路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目大意

有一个有 n n n个点 m m m条边的无向连通图,第 i i i条边连接点 u i u_i ui v i v_i vi,长度为 l i l_i li

你想要求这个图的一棵生成树,并规定一个中心点 m i d mid mid。定义一种规划的拥挤指数为 k × S + ∑ i = 1 n d i s ( i , m i d ) k\times S+\sum\limits_{i=1}^ndis(i,mid) k×S+i=1ndis(i,mid),其中有 k k k表示只被一条边连接的点的数量, d i s ( u , v ) dis(u,v) dis(u,v)表示点 u u u到点 v v v的距离, S S S为给定的常数。

求如何修建道路和规划中心点,才能使拥挤程度最小,以及有多少种方案(求生成树+规划中心点)能使拥挤程度最小。

1 ≤ n ≤ 15 , n − 1 ≤ m ≤ n ( n − 1 ) 2 , 0 ≤ l i , S ≤ 1 0 9 1\leq n\leq 15,n-1\leq m\leq \frac{n(n-1)}{2},0\leq l_i,S\leq 10^9 1n15,n1m2n(n1),0li,S109

时间限制 7000 m s 7000ms 7000ms,空间限制 1024 M B 1024MB 1024MB


题解

我们枚举每个点,让它作为中心点,并找到一个拥挤程度最小的生成树。

我们发现 ∑ i = 1 n d i s ( i , m i d ) \sum\limits_{i=1}^ndis(i,mid) i=1ndis(i,mid)其实等于 ∑ i = 1 n t f i × s i z i \sum\limits_{i=1}^ntf_i\times siz_i i=1ntfi×sizi,其中 l e n i len_i leni表示当 m i d mid mid为根时点 i i i到父亲的距离, s i z i siz_i sizi表示子树 i i i的大小。

因为 n n n比较小,我们可以使用状压 D P DP DP

f [ i ] [ s ] f[i][s] f[i][s]表示当前的根节点为 i i i i i i的子树中点的集合为 s s s时的拥挤程度和方案数(要保存两个数,可以用结构体), g [ i ] [ s ] g[i][s] g[i][s]表示当前根节点为 i i i且根节点只有一个儿子, i i i的子树中(不包括 i i i)的点的集合为 s s s时的拥挤程度和方案数(其实就是一个连通块连出一条边到点 i i i)。注意虽然根节点有可能只被一条边连接,但当 s s s不为点的全集时,这里的 i i i都不算入 k k k中。

初始值为 f [ i ] [ 2 i − 1 ] = { 0 , 1 } f[i][2^{i-1}]=\{0,1\} f[i][2i1]={0,1},其余的 f f f值和 g g g值为 { + ∞ , 0 } \{+\infty,0\} {+,0}。其中第一个数为拥挤程度,第二个数为方案数。

枚举当前状态 s s s,当前点 u u u s s s的子集 t t t,现在 t t t表示要新加入的子树的状态,则转移式为

f [ u ] [ s ] = max ⁡ ( f [ u ] [ s ] , ( f [ u ] [ s ⊕ t ] ∗ g [ u ] [ t ] ) + v ) f[u][s]=\max(f[u][s],(f[u][s\oplus t]*g[u][t])+v) f[u][s]=max(f[u][s],(f[u][st]g[u][t])+v)

其中 max ⁡ \max max表示两个状态取拥挤程度最小的状态,如果拥挤程度相同则将方案数求和。 ∗ * 表示两个状态合并,即拥挤程度相加、方案数相乘。当 s s s为点的全集且 u u u只被一条边连接时 v = S v=S v=S,否则 v = 0 v=0 v=0,这里的 v v v是加在拥挤程度上的。

下面,枚举与 u u u相连且不在 s s s中的点 v v v(这是为能在之后将 v v v加入这个连通块),则转移式为

g [ v ] [ s ] = max ⁡ ( g [ v ] [ s ] , f [ u ] [ s ] + l ∗ c t s + [ c t s = = 1 ] ∗ S ) g[v][s]=\max(g[v][s],f[u][s]+l*ct_s+[ct_s==1]*S) g[v][s]=max(g[v][s],f[u][s]+lcts+[cts==1]S)

其中 max ⁡ \max max + + +的意义同上, l l l表示这条边的长度, c t s ct_s cts表示 s s s的二进制位中 1 1 1的个数(其实就是在算上面的式子 ∑ i = 1 n t f i × s i z i \sum\limits_{i=1}^ntf_i\times siz_i i=1ntfi×sizi),后面 [ c t s = = 1 ] ∗ S [ct_s==1]*S [cts==1]S表示如果 v v v下面只有一个点,也就是有一个只被一条边连接的点,那么拥挤程度要加上 S S S

最后,用每个 f [ i ] [ 2 n − 1 ] f[i][2^n-1] f[i][2n1]来更新 a n s ans ans a n s ans ans也是一个结构体,初始值为 { + ∞ , 0 } \{+\infty,0\} {+,0}),则 a n s ans ans中保存的就是最小的拥挤程度以及能使拥挤程度最小的方案数。

时间复杂度为 O ( 3 n ⋅ n 2 ) O(3^n\cdot n^2) O(3nn2)

code

#include<bits/stdc++.h>
using namespace std;
const int N=15,M=15;
const long long inf=1e15;
int n,m,ct[1<<N];
long long S;
struct node{int y,w;
};
struct dp{long long vl,s;friend dp operator+(dp ax,long long bx){ax.vl+=bx;return ax;}friend dp operator*(dp ax,dp bx){ax.vl+=bx.vl;ax.s*=bx.s;return ax;}
}ans,f[N+5][1<<N],g[N+5][1<<N];
vector<node>G[N+5];
int lb(int i){return i&(-i);}
dp gtmx(dp ax,dp bx){if(ax.vl==bx.vl) ax.s+=bx.s;if(ax.vl<=bx.vl) return ax;return bx;
}
int main()
{
//	freopen("road.in","r",stdin);
//	freopen("road.out","w",stdout);scanf("%d%d%lld",&n,&m,&S);for(int i=1,x,y,w;i<=m;i++){scanf("%d%d%d",&x,&y,&w);G[x].push_back((node){y,w});G[y].push_back((node){x,w});}for(int i=1;i<(1<<n);i++) ct[i]=ct[i^lb(i)]+1;for(int i=1;i<=n;i++){for(int j=0;j<(1<<n);j++){f[i][j]=(dp){inf,0};g[i][j]=(dp){inf,0};}f[i][(1<<i-1)]=(dp){0,1};}for(int s=1;s<(1<<n);s++){for(int u=1;u<=n;u++){if(!((s>>u-1)&1)) continue;int vs=s^(1<<u-1);for(int t=vs;t;t=(t-1)&vs){if(t&lb(vs)){long long v=(s==(1<<n)-1&&t==vs)*S;f[u][s]=gtmx(f[u][s],(f[u][s^t]*g[u][t])+v);}}for(int i=0;i<G[u].size();i++){int v=G[u][i].y,w=G[u][i].w;if((s>>v-1)&1) continue;g[v][s]=gtmx(g[v][s],f[u][s]+w*ct[s]+(ct[s]==1)*S);}}}ans=(dp){inf,0};for(int i=1;i<=n;i++){ans=gtmx(ans,f[i][(1<<n)-1]);}printf("%lld %lld\n",ans.vl,ans.s);return 0;
}

这篇关于2023NOIP A层联测14 修路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/242356

相关文章

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

PMP–一、二、三模–分类–14.敏捷–技巧–看板面板与燃尽图燃起图

文章目录 技巧一模14.敏捷--方法--看板(类似卡片)1、 [单选] 根据项目的特点,项目经理建议选择一种敏捷方法,该方法限制团队成员在任何给定时间执行的任务数。此方法还允许团队提高工作过程中问题和瓶颈的可见性。项目经理建议采用以下哪种方法? 易错14.敏捷--精益、敏捷、看板(类似卡片)--敏捷、精益和看板方法共同的重点在于交付价值、尊重人、减少浪费、透明化、适应变更以及持续改善等方面。

2021-8-14 react笔记-2 创建组件 基本用法

1、目录解析 public中的index.html为入口文件 src目录中文件很乱,先整理文件夹。 新建components 放组件 新建assets放资源   ->/images      ->/css 把乱的文件放进去  修改App.js 根组件和index.js入口文件中的引入路径 2、新建组件 在components文件夹中新建[Name].js文件 //组件名首字母大写

2021-08-14 react笔记-1 安装、环境搭建、创建项目

1、环境 1、安装nodejs 2.安装react脚手架工具 //  cnpm install -g create-react-app 全局安装 2、创建项目 create-react-app [项目名称] 3、运行项目 npm strat  //cd到项目文件夹    进入这个页面  代表运行成功  4、打包 npm run build

用Python实现时间序列模型实战——Day 14: 向量自回归模型 (VAR) 与向量误差修正模型 (VECM)

一、学习内容 1. 向量自回归模型 (VAR) 的基本概念与应用 向量自回归模型 (VAR) 是多元时间序列分析中的一种模型,用于捕捉多个变量之间的相互依赖关系。与单变量自回归模型不同,VAR 模型将多个时间序列作为向量输入,同时对这些变量进行回归分析。 VAR 模型的一般形式为: 其中: ​ 是时间  的变量向量。 是常数向量。​ 是每个时间滞后的回归系数矩阵。​ 是误差项向量,假

PMP–一、二、三模–分类–14.敏捷–技巧–原型MVP

文章目录 技巧一模14.敏捷--原型法--项目生命周期--迭代型生命周期,通过连续的原型或概念验证来改进产品或成果。每个新的原型都能带来新的干系人新的反馈和团队见解。题目中明确提到需要反馈,因此原型法比较好用。23、 [单选] 一个敏捷团队的任务是开发一款机器人。项目经理希望确保在机器人被实际建造之前,团队能够收到关于需求的早期反馈并相应地调整设计。项目经理应该使用以下哪一项来实现这个目标?

C++11/14系列学习

十一假期一直在看C++11新特性,比较出名的书《C++ Primer Plus》专门有一个章节来讲解,《C++ Primer》则将C++11的新特性融入到各个章节来学习。在假期的最后一天无意中发现实验楼有一个专门的教程来讲解,算是念念不忘,必有回响吧,特此整理出来,和大家一起学习。 作者网址:https://www.shiyanlou.com/courses/605,非常感谢! 注:本文并没有智

C++笔试强训12、13、14

文章目录 笔试强训12一、选择题1-5题6-10题 二、编程题题目一题目二 笔试强训13一、选择题1-5题6-10题 二、编程题题目一题目二 笔试强训14一、选择题1-5题6-10题 二、编程题题目一题目二 笔试强训12 一、选择题 1-5题 引用:是一个别名,与其被引用的实体公用一份内存空间,编译器不会给引用变量单独开辟新的空间。A错误 故选A。 A

从零开始学cv-14:图像边缘检测

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、图像边缘是什么?二、Sobel 算子三、Scharr 算子四、Prewitt算子五、Canny算子 前言 边缘检测是OpenCV中的一个重要组成部分,它用于识别图像中亮度变化显著的点,即边缘。通过边缘检测,我们可以从图像中提取出重要的特征,为后续的图像分析、形状识别和物体跟踪等任务奠定

java基础总结14-面向对象10(多态)

面向对象最核心的机制——动态绑定,也叫多态 1 通过下面的例子理解动态绑定,即多态 package javastudy.summary;class Animal {/*** 声明一个私有的成员变量name。*/private String name;/*** 在Animal类自定义的构造方法* @param name*/Animal(String name) {this.name = n