题意:给你一棵树,要选择若干节点,若一个点i没有选择,则有\(d(dis(i,j))\)的代价,其中j被选择。选择一个点代价为k,求最小代价。

首先,考虑这样一个问题:

如果距离a的最近被选点为i,距离b的最近被选点也是i,那么a到b的路径上的点的最近被选点都是i。

考虑一条链:设Ax是链上第x个点,那么点y到Ax的距离fy(x)随x的增加,先下降,再上升。(这个显然)。

那么假设a到b路径上的c,最近点不是i而是j。

那么,\(dis(a,i)<dis(a,j),dis(c,i)>dis(c,j),dis(b,i)<dis(b,j)\)。

就是说\(fi\)和\(fj\)有两个交点。但这是不可能的。

所以,如果距离a的最近被选点为i,距离b的最近被选点也是i,那么a到b的路径上的点的最近被选点都是i一定成立。

换句话说,以i为最近点的j是一个连通块。

这样,我们设\(dp(i,j)\)表示i的最近点是j的状态。再维护\(f(i)\)表示\(dp(i,j)\)的最小值。

那么,对于i的每个儿子v,枚举它的最近点a,则转移到\(dp(v,a)\)。

但如果\(j=a\),那么对于v来说,a已经选择过了,则转移到\(dp(v,a)-k\)。

维护\(f(i)\)后就是\(dp(i,j)=min(f(v),dp(v,j)-k)+d(dis(i,j))+k\)。

因为要输出方案,再记录一下转移的位置。

\(dis\)数组可以\(O(n^2)\)预处理出。

代码:

#include <stdio.h>
int fr[182],ne[362],v[362],bs = 0;
void addb(int a, int b) {
v[bs] = b;
ne[bs] = fr[a];
fr[a] = bs++;
}
int dp[182][182],wz[182],sz[182],cd[182][182],n,k;
int fa[182],sd[182],ans[182],zy[362][182];
void dfs0(int u, int f) {
fa[u] = f;
sd[u] = sd[f] + 1;
for (int i = fr[u]; i != -1; i = ne[i]) {
if (v[i] != f) dfs0(v[i], u);
}
}
int dfscd(int a, int b) {
if (a == b) return 0;
if (cd[a][b]) return cd[a][b];
if (sd[a] > sd[b]) cd[a][b] = dfscd(fa[a], b) + 1;
else cd[a][b] = dfscd(a, fa[b]) + 1;
return cd[a][b];
}
void dfs(int u, int f) {
for (int i = fr[u]; i != -1; i = ne[i]) {
if (v[i] != f) dfs(v[i], u);
}
for (int a = 1; a <= n; a++) {
dp[u][a] = sz[cd[u][a]] + k;
for (int i = fr[u]; i != -1; i = ne[i]) {
if (v[i] == f) continue;
int t = dp[v[i]][wz[v[i]]];
if (dp[v[i]][a] - k < t) {
t = dp[v[i]][a] - k;
zy[i][a] = a;
} else zy[i][a] = wz[v[i]];
dp[u][a] += t;
}
if (a == 1 || dp[u][a] < dp[u][wz[u]]) wz[u] = a;
}
}
void dfs1(int u, int f, int a) {
ans[u] = a;
for (int i = fr[u]; i != -1; i = ne[i]) {
if (v[i] != f) dfs1(v[i], u, zy[i][a]);
}
}
int main() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) fr[i] = -1;
for (int i = 1; i < n; i++) scanf("%d", &sz[i]);
for (int i = 0; i < n - 1; i++) {
int a,b;
scanf("%d%d", &a, &b);
addb(a, b);
addb(b, a);
}
dfs0(1, 0);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i != j && cd[i][j] == 0) dfscd(i, j);
}
}
dfs(1, 0);
int z = 1;
for (int i = 2; i <= n; i++) {
if (dp[1][i] < dp[1][z]) z = i;
}
printf("%d\n", dp[1][z]);
dfs1(1, 0, z);
for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
return 0;
}

CF70E Information Reform的更多相关文章

  1. 用信息值进行特征选择(Information Value)

    Posted by c cm on January 3, 2014 特征选择(feature selection)或者变量选择(variable selection)是在建模之前的重要一步.数据接口越 ...

  2. iOS之使用模拟器报错:resource fork, Finder information, or similar detritus not allowed

    很奇怪的问题,使用真机测试没有问题.但使用模拟器测试的时候就会报这样的错误,错误类型为:Code Sign Error 错误提示是这样:resource fork, Finder informatio ...

  3. Information Management Policy(信息管理策略)的使用范例

    基础知识 很多人都会定期收拾自己的书架或者抽屉,把里面过旧的资料拿走,为新的资料腾出空间来,这样既可以节省空间,而且当冗余资料过多的时候也会降低你查找的速度和效率.那么,在企业的SharePoint中 ...

  4. Android Studio安装以及Fetching android sdk component information超时的解决方案

    转载:http://www.cnblogs.com/sonyi/p/4154797.html 在经过两年的开发之本后,Google 公司终于发布了 Android Studio 1.0,喜欢折腾的童鞋 ...

  5. iOS Xcode, 解决“Could not insert new outlet connection: Could not find any information for the class named”的问题。

    在Xcode中,我们可以在StoryBoard编辑界面或者是xib编辑界面中通过“Control键+拖拽“的方式将某个界面元素和对应的代码文件连接起来,在代码文件中创建outlet. 不过,如果你的运 ...

  6. ORA-00824: cannot set sga_target due to existing internal settings, see alert log for more information

    这篇文章是上篇文章”Expdp 导数错误 ORA-00832”的延续,前几天工作比较忙.累,直到今天才整理发出来.这个数据库实例的参数设置比较诡异其实是有原因的,由于这台数据库服务器系统是32位,数据 ...

  7. MS SQL Could not obtain information about Windows NT group/user 'domain\login', error code 0x5. [SQLSTATE 42000] (Error 15404)

    最近碰到一个有趣的错误:海外的一台数据库服务器上某些作业偶尔会报错,报错信息如下所示: -------------------------------------------------------- ...

  8. MS SQL错误:SQL Server failed with error code 0xc0000000 to spawn a thread to process a new login or connection. Check the SQL Server error log and the Windows event logs for information about possible related problems

          早晨宁波那边的IT人员打电话告知数据库无法访问了.其实我在早晨也发现Ignite监控下的宁波的数据库服务器出现了异常,但是当时正在检查查看其它服务器发过来的各类邮件,还没等到我去确认具体情 ...

  9. Could not obtain information about Windows NT group/user 'xxxx\xxxx', error code 0x5

    案例描述 昨晚踢球回来,接到电话说一个系统的几个比较重要作业出错,导致系统数据有些问题.让我赶紧检查看看.检查作业日志时发现,作业报如下错误(关键信息用xxx替换) The job failed.  ...

随机推荐

  1. qt-博客

    将QQ中的图文聊天内容显示到Qt界面: http://www.qter.org/portal.php?mod=view&aid=12

  2. java——内存中的数组

    数组是一种引用类型,数组引用变量只是一个引用,数组元素和数组变量在内存中时分开存放的,下面我们看一下基本类型的数组和引用类型的数组在内存中的地址分布情况 基本类型数组: 我们先来看一段代码: publ ...

  3. (六)Struts的简单异常处理

    一.异常的分类 1.1 struts中的异常概念 Struts的声明式异常: 不处理异常,将异常交给struts框架来处理. 1.2 局部异常 局部异常:异常定义在Action里,异常处理只在这个Ac ...

  4. 数据结构-平衡二叉树Java实现

    1,Node.java package com.cnblogs.mufasa.BalanceBinaryTree; public class Node { Node parent; Node left ...

  5. MFC如何显示位图

    1. 资源文件中加载 bmp 2.1. 静态加载图片 在属性下设置为如下即可 2.2 动态加载图片 其中要在控件中添加CStatic变量,并且属性设置为如下 并且在按钮控件中加入 如下代码 void ...

  6. C# 哥德巴赫猜想的实现方式 region分区编写

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  7. vue使用layer主动关闭弹窗

    关闭当前框的弹出层 layer.close(layer.index); 刷新父层 parent.location.reload(); // 父页面刷新 关闭iframe 弹出的全屏层 var inde ...

  8. 【转载】salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句

    salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句 salesforce如果简单的说可以大概分成两个部分:Apex,VisualForce Page. 其中Apex ...

  9. 【SQL server】SQL server基础(一)

    一.关系型数据库 关系型数据库的基本元素是二维表,这些二维表可以被独立或者通过join语句连接起来使用.主键和外键是用来连接二维表之间的主要工具 1.主键(primary key)和外键(foreig ...

  10. Bind Mounts and File System Mount Order

         When you use the bind option of the mount command, you must be sure that the file systems are m ...