BZOJ3257 : 树的难题
设$f[x][i][j]$表示以$x$为根的子树,与$x$连通部分有$i$个黑点,$j$个白点,不联通部分都是均衡的最小代价。若$i>1$,则视作$1$;若$j>2$,则视作$2$。
然后进行树形DP即可,转移的时候如果不要那棵子树,那么那棵子树的状态必须满足$!i||j<2$。
时间复杂度$O(n)$。
#include<cstdio>
#define rep(i,n) for(int i=0;i<n;i++)
typedef long long ll;
const int N=300010;
const ll inf=1LL<<60;
int T,n,i,x,y,z,a[N],g[N],v[N<<1],w[N<<1],nxt[N<<1],ed;
ll f[N][2][3],h[2][3],ans;
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
inline void up(ll&a,ll b){if(a>b)a=b;}
inline void add(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
inline int fix(int x){return x<2?x:2;}
void dfs(int x,int y){
rep(A,2)rep(B,3)f[x][A][B]=inf;
f[x][0][0]=0;
for(int i=g[x];i;i=nxt[i])if(v[i]!=y){
int u=v[i];
dfs(u,x);
rep(A,2)rep(B,3)h[A][B]=inf;
rep(A,2)rep(B,3)if(f[x][A][B]<inf)rep(C,2)rep(D,3)if(f[u][C][D]<inf){
up(h[A|C][fix(B+D)],f[x][A][B]+f[u][C][D]);
if(!C||D<2)up(h[A][B],f[x][A][B]+f[u][C][D]+w[i]);
}
rep(A,2)rep(B,3)f[x][A][B]=h[A][B];
}
rep(A,2)rep(B,3)h[A][B]=inf;
rep(A,2)rep(B,3)if(f[x][A][B]<inf)up(h[A|!a[x]][fix(B+(a[x]==1))],f[x][A][B]);
rep(A,2)rep(B,3)f[x][A][B]=h[A][B];
}
int main(){
for(read(T);T--;printf("%lld\n",ans)){
read(n);
for(ed=0,i=1;i<=n;i++)read(a[i]),g[i]=0;
for(i=1;i<n;i++)read(x),read(y),read(z),add(x,y,z),add(y,x,z);
dfs(1,0);
ans=inf;
rep(A,2)rep(B,3)if(!A||B<2)up(ans,h[A][B]);
}
return 0;
}
BZOJ3257 : 树的难题的更多相关文章
- [BJOI2017]树的难题 点分治 线段树
题面 [BJOI2017]树的难题 题解 考虑点分治. 对于每个点,将所有边按照颜色排序. 那么只需要考虑如何合并2条链. 有2种情况. 合并路径的接口处2条路径颜色不同 合并路径的接口处2条路径颜色 ...
- [BJOI2017]树的难题 点分治,线段树合并
[BJOI2017]树的难题 LG传送门 点分治+线段树合并. 我不会写单调队列,所以就写了好写的线段树. 考虑对于每一个分治中心,把出边按颜色排序,这样就能把颜色相同的子树放在一起处理.用一棵动态开 ...
- BZOJ4860 BJOI2017 树的难题 点分治、线段树合并
传送门 只会线段树……关于单调队列的解法可以去看“重建计划”一题. 看到路径长度$\in [L,R]$考虑点分治.可以知道,在当前分治中心向其他点的路径中,始边(也就是分治中心到对应子树的根的那一条边 ...
- 【XSY2307】树的难题
Description Solution 看到这种路径统计问题,一般就想到要用点分治去做. 对于每个重心\(u\),统计经过\(u\)的合法的路径之中的最大值. 第一类路径是从\(u\)出发的,直接逐 ...
- [bzoj4860] [BeiJing2017]树的难题
Description 给你一棵 n 个点的无根树.树上的每条边具有颜色. 一共有 m 种颜色,编号为 1 到 m.第 i 种颜色的权值为 ci.对于一条树上的简单路径,路径上经过的所有边按顺序组成一 ...
- bzoj 4860 [BeiJing2017]树的难题
题面 https://www.lydsy.com/JudgeOnline/problem.php?id=4860 题解 点分治 设当前重心为v 假设已经把所有边按照出发点第一关键字, 颜色第二关键字排 ...
- 并不对劲的loj2179:p3714:[BJOI2017]树的难题
题目大意 有一棵树,\(n\)(\(n\leq2*10^5\))个点,每条边\(i\)有颜色\(w_i\),共有\(m\)(\(m\leq n\))种颜色,第\(i\)种颜色的权值是\(c_i\)(\ ...
- [JZOJ3347] 【NOI2013模拟】树的难题
题目 题目大意 给你一棵树,每个节点有三种黑.白.灰三种颜色. 你要割掉一些边(每条边被割需要付出一定的代价),使得森林的每棵树满足: 没有黑点或至多一个白点. 思考历程 这题一看就知道是一个树形DP ...
- G 树的难题
时间限制 : 10000 MS 空间限制 : 165536 KB 评测说明 : 1s,128m 问题描述 给出一个无根树.树有N个点,边有权值.每个点都有颜色,是黑色.白色.灰色这三种颜色之一,称 ...
随机推荐
- Codeforces Round #371 (Div. 2)(set\unique)
B. Filya and Homework time limit per test 1 second memory limit per test 256 megabytes input standar ...
- Android Tab -- 使用ViewPager、PagerAdapter来实现
原文地址:http://blog.csdn.net/crazy1235/article/details/42678877 效果:滑动切换,自动切换. 代码:https://github.com/ldb ...
- linux退出vi
linux退出vi操作,可以先按“esc”,再按“:”,“x”即可,这是要保存退出. 假如是修改过的,不保存,即是:先按 : ,然后输入 q! 回车 假如未改动,即先按 : ,然后输入 ...
- **PHP中替换换行符
PHP中替换换行符 php 不同系统的换行不同系统之间换行的实现是不一样的linux 与unix中用 \nMAC 用 \rwindow 为了体现与linux不同 则是 \r\n所以在不同平台上 实现方 ...
- Pyqt QDockWidget 停靠窗体
网上的一个关于QDockWidget 停靠窗体的教程 代码: # -*- coding: utf-8 -*- from PyQt4.QtGui import * from PyQt4.QtCore i ...
- SQL Server创建随机测试数据
我们在做数据仓库开发的过程中,经常需要插入大量的测试数据来测试数据库查询性能和计算占用的存储空间等.本文主要介绍下不借用第三方的工具在数据库中直接生成大量的测试数据. 需求 每一行包含5个日期字段和一 ...
- 一致性hash算法简介与代码实现
一.简介: 一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义: 1.平衡性(Balance) 2.单调性(Monotonicity) 3.分散性(Spread) 4.负 ...
- 使用nbrbutil工具來處理requested media id is in use, cannot process request
首先我發現一個Media已經過期很久,但是并不會覆蓋重用 使用bpexpdate手動過期,失敗,讓他deassigned也不行 使用bpimmedia查看上面的image也沒有 我嘗試手動去過期,返回 ...
- 使用windows的远程桌面连接连接Ubuntu
想起来用笔记本连接一个windows server时只需要在远程桌面连接里面输入一下ip地址然后账号密码就可以了,十分简单.于是乎既然装了个Ubuntu当服务器使那么我就业来远程连接一下,由于wind ...
- [UI]实用案例--Shape绘制实用圆圈
Android允许通过xml定义资源,常见的事string,id,integer,dimen等,也可以定义一些图片资源,比如用来做几何的矢量图就非常好用,其中有许多的细节问题,具体需求可以再结合goo ...