【点分治】hdu5016 Mart Master II
点分治好题。
①手动开栈。
②dp预处理每个点被哪个市场控制,及其距离是多少,记作pair<int,int>数组p。
③设dis[u].first为u到重心s的距离,dis[u].second=u,到在统计的时候,若dis[u]<=(p[v].first-dis[v].first,p[v].second)(双关键字比较),则符合题意,当然这样在计算同一颗子树里的答案时,是压根不对的,但是既然这部分反正是要被减掉的,那就将错就错地计算即可了。
④最后在所有原非市场节点的ans中取一个最大的即可。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
using namespace std;
#define MAXN 100001
#define INF 1000000000
typedef pair<int,int> Point;
Point td[MAXN],ds[MAXN],p[MAXN],td2[MAXN],ds2[MAXN];
bool is[MAXN];
int n,K,ans[MAXN],en2,en3;
int v[MAXN<<],w[MAXN<<],first[MAXN],next[MAXN<<],en;
void AddEdge(const int &U,const int &V,const int &W)
{
v[++en]=V;
w[en]=W;
next[en]=first[U];
first[U]=en;
}
bool centroid[MAXN];
int size[MAXN];
int calc_sizes(int U,int Fa)
{
int res=;
for(int i=first[U];i;i=next[i])
if(v[i]!=Fa&&(!centroid[v[i]]))
res+=calc_sizes(v[i],U);
return size[U]=res;
}
Point calc_centroid(int U,int Fa,int nn)
{
Point res=make_pair(INF,-);
int sum=,maxv=;
for(int i=first[U];i;i=next[i])
if(v[i]!=Fa&&(!centroid[v[i]]))
{
res=min(res,calc_centroid(v[i],U,nn));
maxv=max(maxv,size[v[i]]);
sum+=size[v[i]];
}
maxv=max(maxv,nn-sum);
res=min(res,make_pair(maxv,U));
return res;
}
void calc_dis(int U,int Fa,int d)
{
td[en2++]=make_pair(d,U);
for(int i=first[U];i;i=next[i])
if(v[i]!=Fa&&(!centroid[v[i]]))
calc_dis(v[i],U,d+w[i]);
}
void calc_pairs(Point dis[],Point dis2[],int En,int op)
{
sort(dis2,dis2+En);
for(int i=;i<En;++i)
ans[dis[i].second]+=(dis2+En-lower_bound(dis2,dis2+En,dis[i]))*op;
}
void solve(int U)
{
calc_sizes(U,-);
int s=calc_centroid(U,-,size[U]).second;
centroid[s]=;
for(int i=first[s];i;i=next[i])
if(!centroid[v[i]])
solve(v[i]);
en3=;
ds[en3]=make_pair(,s);
ds2[en3++]=make_pair(p[s].first,p[s].second);
for(int i=first[s];i;i=next[i])
if(!centroid[v[i]])
{
en2=; calc_dis(v[i],s,w[i]);
for(int i=;i<en2;++i)
td2[i]=make_pair(p[td[i].second].first-td[i].first,p[td[i].second].second);
calc_pairs(td,td2,en2,-);
memcpy(ds+en3,td,en2*sizeof(Point));
memcpy(ds2+en3,td2,en2*sizeof(Point));
en3+=en2;
}
calc_pairs(ds,ds2,en3,);
centroid[s]=;
}
void init()
{
memset(ans,,(n+)*sizeof(int));
memset(first,,(n+)*sizeof(int));
en=;
}
void dfs1(int U,int Fa)
{
for(int i=first[U];i;i=next[i])
if(v[i]!=Fa)
{
p[v[i]]=min(p[v[i]],make_pair(p[U].first+w[i],p[U].second));
dfs1(v[i],U);
}
}
void dfs2(int U,int Fa)
{
for(int i=first[U];i;i=next[i])
if(v[i]!=Fa)
{
dfs2(v[i],U);
p[U]=min(p[U],make_pair(p[v[i]].first+w[i],p[v[i]].second));
}
}
int main()
{
int a,b,c;
while(scanf("%d",&n)!=EOF)
{
init();
for(int i=;i<n;++i)
{
scanf("%d%d%d",&a,&b,&c);
AddEdge(a,b,c);
AddEdge(b,a,c);
}
for(int i=;i<=n;++i)
{
scanf("%d",&is[i]);
if(!is[i]) p[i]=make_pair(INF,INF);
else p[i]=make_pair(,i);
}
dfs2(,-);
dfs1(,-);
solve();
int Ans=;
for(int i=;i<=n;++i) if(!is[i]) Ans=max(Ans,ans[i]);
printf("%d\n",Ans);
}
return ;
}
【点分治】hdu5016 Mart Master II的更多相关文章
- HDU 5016 Mart Master II
Mart Master II Time Limit: 6000ms Memory Limit: 65536KB This problem will be judged on HDU. Original ...
- HDU 5016 Mart Master II (树上点分治)
题目地址:pid=5016">HDU 5016 先两遍DFS预处理出每一个点距近期的基站的距离与基站的编号. 然后找重心.求出每一个点距重心的距离.然后依据dis[x]+dis[y] ...
- 算法学习分析-点分治 HDU 6269 Master of Subgraph
首先给出定义 点分治是一种处理树上路径的工具 挂出一道题目来:Master of Subgraph 这道题目让你求所有联通子图加和所能产生数字,问你1到m之间,那些数字可以被产生 这道题目,假如我们利 ...
- hdu 5016 点分治(2014 ACM/ICPC Asia Regional Xi'an Online)
Mart Master II Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- HDU 4916 树分治
Mart Master II Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- 【SpringBoot】SpringBoot 入门示例
参考资料: http://www.tuicool.com/articles/mqeee2A http://www.cnblogs.com/suncj/p/4065589.html http://spr ...
- 【架构】SpringCloud 注册中心、负载均衡、熔断器、调用监控、API网关示例
示例代码: https://github.com/junneyang/springcloud-demo 参考资料: SpringCloud系列 Eureka 一句话概括下spring框架及spring ...
- Bryce1010 Acm模板
目录 STL标准模板库 STL简介 STL pair STL set STL vector STL string STL stack STL queue STL map upper_bound和low ...
- Mac下OpenCV开发
1. 环境搭建 a) 安装Homebrew i. 下载地址:http://github.com/mxcl/homebrew/tarball/maste ...
随机推荐
- Spring源码解析-基于注解依赖注入
在spring2.5版本提供了注解的依赖注入功能,可以减少对xml配置. 主要使用的是 AnnotationConfigApplicationContext: 一个注解配置上下文 AutowiredA ...
- MFC 对话框透明效果
网上找的资料自己改了改,在这里记录和分享一下,主要是TransparentWnd函数. 在子类的OnShowWindow函数中调用 ShowWindowAlpha() #pragma once tem ...
- MySQL 8.0.11(zip)安装及配置
(1)下载MySQL8.0.11: (2)解压zip文件: 我解压到了D:/MySQL/mysql-8.0.11-winx64 (3)配置环境变量: 右键此电脑->属性 高级系统设置 环境变 ...
- P值
https://baike.baidu.com/item/P%E5%80%BC/7083622?fr=aladdin https://baijiahao.baidu.com/s?id=15960976 ...
- 51Nod 1421
1421 最大MOD值 有一个a数组,里面有n个整数.现在要从中找到两个数字(可以是同一个) ai,aj ,使得 ai mod aj 最大并且 ai ≥ aj. Input 单组测试数据. 第一行包含 ...
- 【poj3693-重复次数最多的连续重复子串】后缀数组
题意:给定一个串,长度<=10^5,求它重复次数最多的连续重复子串(输出字典序最小的那个). 例如ccabcabc,答案就是abcabc 一开始没想清楚,结果调了好久. 原理: 按照L划分,因为 ...
- 「6月雅礼集训 2017 Day1」看无可看
[题目大意] 给出n个数,a[1]...a[n],称作集合S,求
- 51nod 1076 2条不相交的路径
给出一个无向图G的顶点V和边E.进行Q次查询,查询从G的某个顶点V[s]到另一个顶点V[t],是否存在2条不相交的路径.(两条路径不经过相同的边) (注,无向图中不存在重边,也就是说确定起点和终点 ...
- [bzoj1015][JSOI2008]星球大战——并查集+离线处理
题解 给定一张图,支持删点和询问连通块个数 按操作顺序处理的话要在删除点的同时维护图的形态(即图具体的连边情况),这是几乎不可做的 我们发现,这道题可以先读入操作,把没删的点的边先连上,然后再倒序处理 ...
- bzoj 1192 二进制
原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1192 继续刷水题,二进制思想 //By BLADEVIL var x :longint; ...