[ZPG TEST 108] blockenemy【树形dp】
T3:blockenemy
blockenemy.pas/in/out 128M 1s
你在玩电子游戏的时候遇到了麻烦。。。。。。
你玩的游戏是在一个虚拟的城市里进行,这个城市里有n个点,都从0~n-1编了号,每两个点之间有且仅有一条路径。现在,你的敌人到这个城市来踩点了!!!为了阻止他们更好的踩点,
你决定切断他们所有踩点人员的联系,使他们孤军作战,然后在各个击破。但是这就要切断某些街道,而你每切断一条路,市民就会产生相对的不满值,不满值越大,城市的和谐度就越小。所以你现在需要知道为了使踩点人员所在的点两两之间不联通所切断的边产生的最小不满值是多少?
Input
第一行一个数:n n<=50
以下n-1行,每行3个数 a,b,c 表示a点和b点之间有条路,切断这条路的不满值为c
以下若干行 每行一个数,表示踩点人员的位置
Output
一个数,最小不满值
Sample Input
5
1 0 1
1 2 2
0 3 3
4 0 4
3
2
4
Sample Output
4
据说这道题有许多做法,直接复制题面的第一句话到百度里搜索,就会有别人的做法,我的做法是std的,想了好久才搞定。
对于每个节点i,令f(i, 0)表示以i为根的子树中,全部敌人两两不连通,且全部都无法到达点i的最小值;f(i, 1)表示以i为根的子树中,全部敌人两两不连通,但有1个敌人可以到底点i的最小值。状态设计好了,接下来就是分两种情况转移:
情况①:若i这个点有敌人。显然,f(i, 0)肯定为inf了,因为不可能做到“全部都无法到达点i”。f(i, 1) = sigma(min(f(j, 1) + w(i, j), f(j, 0))),其中j属于i的儿子。
情况②:若i这个点没敌人。那么
f(i, 0) = sigma(min(f(j, 1) + w(i, j), f(j, 0))),其中j属于i的儿子。
f(i, 1)的转移有那么一丢丢难想。f(i, 1)一定实在f(i, 0)的基础上,使得某个儿子从不能到达i,变成能到达i,即对于儿子j,对该状态的贡献由min(f(j, 1) + w, f(j, 0))变为f(j, 1).如果这样的话,f(i, 1)就会在f(i, 0)的基础上减去min(f(j, 1) + w, f(j, 0)) - f(j, 1),那么这个值越大,f(i, 1)就会越小。
#include <cstdio>
#include <cstdlib>
#include <cstring> const int maxn = 55; int n, t1, t2, t3, root, f[maxn][2];
bool book[maxn];
struct graph {
int head[maxn], to[maxn << 1], next[maxn << 1], w[maxn << 1], lb;
graph(void) {
memset(head, -1, sizeof head);
memset(next, -1, sizeof next);
lb = 0;
}
void ist(int aa, int ss, int ww) {
to[lb] = ss;
w[lb] = ww;
next[lb] = head[aa];
head[aa] = lb;
++lb;
}
} g; inline int minn(int aa, int ss) {
return aa < ss? aa: ss;
}
inline int maxx(int aa, int ss) {
return aa > ss? aa: ss;
}
void dfs(int r, int p) {
if (book[r]) {
f[r][0] = 0x3c3c3c3c;
for (int j = g.head[r]; j != -1; j = g.next[j]) {
if (g.to[j] != p) {
dfs(g.to[j], r);
f[r][1] += minn(f[g.to[j]][1] + g.w[j], f[g.to[j]][0]);
}
}
}
else {
int mx = 0, mn;
for (int j = g.head[r]; j != -1; j = g.next[j]) {
if (g.to[j] != p) {
dfs(g.to[j], r);
mn = minn(f[g.to[j]][0], f[g.to[j]][1] + g.w[j]);
f[r][0] += mn;
mx = maxx(mx, mn - f[g.to[j]][1]);
}
}
f[r][1] = f[r][0] - mx;
}
} int main(void) {
freopen("blockenemy.in", "r", stdin);
freopen("blockenemy.out", "w", stdout);
scanf("%d", &n);
unsigned seed;
for (int i = 1; i < n; ++i) {
scanf("%d%d%d", &t1, &t2, &t3);
seed += t1 + t2 + t3;
g.ist(t1, t2, t3);
g.ist(t2, t1, t3);
}
while (scanf("%d", &t1) != EOF) {
book[t1] = true;
seed += t1;
} srand(seed);
root = rand() % n;
dfs(root, -1);
printf("%d\n", f[root][1]);
return 0;
}
[ZPG TEST 108] blockenemy【树形dp】的更多相关文章
- [vijos 1642]班长的任务 [树形dp]
背景 十八居士的毕业典礼(1) 描述 福州时代中学2009届十班同学毕业了,于是班长PRT开始筹办毕业晚会,但是由于条件有限,可能每个同学不能都去,但每个人都有一个权值,PRT希望来的同学们的权值总和 ...
- [CEOI2007]树的匹配Treasury(树形DP+高精)
题意 给一棵树,你可以匹配有边相连的两个点,问你这棵树的最大匹配时多少,并且计算出有多少种最大匹配. N≤1000,其中40%的数据答案不超过 108 题解 显然的树形DP+高精. 这题是作为考试题考 ...
- poj3417 LCA + 树形dp
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
- COGS 2532. [HZOI 2016]树之美 树形dp
可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...
- 【BZOJ-4726】Sabota? 树形DP
4726: [POI2017]Sabota? Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 128 Solved ...
- 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...
- 树形DP
切题ing!!!!! HDU 2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...
- BZOJ 2286 消耗战 (虚树+树形DP)
给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...
- POJ2342 树形dp
原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...
随机推荐
- centos、mac的grafana安装和简单使用
1.安装: 参考官方文档安装说明:https://grafana.com/grafana/download Redhat & Centos(64 Bit): wget https://s3-u ...
- jenkins的构建日志(console output)分类解析
每个jenkins的job构建过程中会产生大量日志,如何快速找到或者查看我们关心的日志显得很有意义,为此jenkins提供了一个插件“Log Parser Plugin”可以帮助我们完成这个任务. 1 ...
- 字符设备之poll机制
poll机制作用:相当于一个定时器.时间到了还没有资源就唤醒进程. 主要用途就是:进程设置一段时间用来等待资源,假设时间到了资源还没有到来,进程就立马从睡眠状态唤醒不再等待.当然这仅仅是使用于这段时间 ...
- 设计模式C++实现_2_简单工厂模式
简单工厂模式 主要用于创建对象. 新加入类时. 不会影响曾经的系统代码. 核心思想是用一个工厂来依据输入的条件产生不同的类,然后依据不同类的 virtual 函数得到不同的结果. 以下以苹果手机的生产 ...
- 原生js 平滑滚动到页面的某个位置
window.scrollTo() 语法1: window.scrollTo(x-coord,y-coord) x-coord 是文档中的横轴坐标. y-coord 是文档中的纵轴坐标. 例子: w ...
- Android ImageLoader 本地缓存
Android ImageLoader 本地缓存 本地缓存 ...
- [办公自动化]计算机突然断电,微软office文档(有asd文件)如何恢复?
今天同事使用office软件时,突然故障.结果他忙了半天的word文档内容都找不见了. 经过查找,在其硬盘根目录找到了asd文档. 但是用当前版本的word和高版本的word软件都无法打开. 又查找了 ...
- C#中,变量前的@符号
看别人写的C#代码,发现有变量前带@,啥意思? string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling& ...
- 2016/3/27 PHP中include和require的区别详解
1.概要 require()语句的性能与include()相类似,都是包括并运行指定文件.不同之处在于:对include()语句来说,在执行文件时每次都要进行读取和评估:而对于require()来说, ...
- 5.eclipse 自带的jdk没有源码,改了它
其实JDK源码在安装的时候已经放在了jdk所在的目录下,只是eclipse使用 了不带有源码的jre,导致没找到对应的源码,点击 Window->Perference->Java-> ...