点分治好题。

①手动开栈。

②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的更多相关文章

  1. HDU 5016 Mart Master II

    Mart Master II Time Limit: 6000ms Memory Limit: 65536KB This problem will be judged on HDU. Original ...

  2. HDU 5016 Mart Master II (树上点分治)

    题目地址:pid=5016">HDU 5016 先两遍DFS预处理出每一个点距近期的基站的距离与基站的编号. 然后找重心.求出每一个点距重心的距离.然后依据dis[x]+dis[y] ...

  3. 算法学习分析-点分治 HDU 6269 Master of Subgraph

    首先给出定义 点分治是一种处理树上路径的工具 挂出一道题目来:Master of Subgraph 这道题目让你求所有联通子图加和所能产生数字,问你1到m之间,那些数字可以被产生 这道题目,假如我们利 ...

  4. 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 ...

  5. HDU 4916 树分治

    Mart Master II Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  6. 【SpringBoot】SpringBoot 入门示例

    参考资料: http://www.tuicool.com/articles/mqeee2A http://www.cnblogs.com/suncj/p/4065589.html http://spr ...

  7. 【架构】SpringCloud 注册中心、负载均衡、熔断器、调用监控、API网关示例

    示例代码: https://github.com/junneyang/springcloud-demo 参考资料: SpringCloud系列 Eureka 一句话概括下spring框架及spring ...

  8. Bryce1010 Acm模板

    目录 STL标准模板库 STL简介 STL pair STL set STL vector STL string STL stack STL queue STL map upper_bound和low ...

  9. Mac下OpenCV开发

    1.         环境搭建 a)       安装Homebrew i.            下载地址:http://github.com/mxcl/homebrew/tarball/maste ...

随机推荐

  1. 如何用listview显示服务端数据

    https://www.cnblogs.com/caobotao/p/5061627.html

  2. wget下载HTTPS链接

    wget -c -O master.zip --no-check-certificate https://github.com/mitsuhiko/flask/archive/master.zip # ...

  3. ICE学习笔记一----运行官方的java版demo程序

    建议新手和我一样,从官网下载英文文档,开个有道词典,慢慢啃. 官方文档下载: http://download.csdn.net/detail/xiong_mao_1/6300631 程序代码就不说了, ...

  4. spring aop与aspectj

    AOP:面向切面编程 简介 AOP解决的问题:将核心业务代码与外围业务(日志记录.权限校验.异常处理.事务控制)代码分离出来,提高模块化,降低代码耦合度,使职责更单一. AOP应用场景: 日志记录.权 ...

  5. 拉格朗日乘数法 和 KTT条件

    预备知识 令 \(X\) 表示一个变量组(向量) \((x_1, x_2, \cdots, x_n)\) 考虑一个处处可导的函数 \(f(X)\), 为了方便描述, 这里以二元函数为例 对于微分, 考 ...

  6. camera驱动框架分析(下)

    sensor的驱动 v4l2_i2c_new_subdev_board先用client = i2c_new_device(adapter, info);创建info对应的i2c_client对象(代表 ...

  7. python 学习笔记 多进程

    要让python程序实现多进程,我们先了解操作系统的相关知识 Unix/Linux操作系统提供了一个fork()系统调用,他非常特殊,普通的函数调用,调用一次,返回一次,但是fork调用一次, 返回两 ...

  8. Oracle基础 02 临时表空间 temp

    --查看临时文件的使用/剩余空间 SQL> select * from v$temp_space_header; --查看SCOTT用户所属的临时表空间 SQL> select usern ...

  9. xshell命令大全

    suse linux 常用命令 (1)命令ls——列出文件 ls -la 给出当前目录下所有文件的一个长列表,包括以句点开头的“隐藏”文件 ls a* 列出当前目录下以字母a开头的所有文件 ls -l ...

  10. KDJ回测

    # -*- coding: utf-8 -*- import os import pandas as pd # ========== 遍历数据文件夹中所有股票文件的文件名,得到股票代码列表stock_ ...