点分治好题。

①手动开栈。

②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. 封装安卓的okhttp

    1.封装了get方法,handler更新主线程,回调的onsuccess,onfailure,onerror等方法 2.配置文件 api 'com.android.support:recyclervi ...

  2. POJ2559 Largest Rectangle in a Histogram (单调栈

    Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 26012 ...

  3. 解读python小练习

    1.新建一个函数,判断是不是int 类型,并测试,不是抛出错误def adder(x, y):"""Return x + y if they are both integ ...

  4. 团队代码中Bug太多怎么办?怎样稳步提高团队的代码质量

    最近负责的Android APP项目,由于团队成员变动.界面改版导致代码大幅修改等原因,产品发布后屡屡出现BUG导致的程序崩溃. 经过对异常统计和代码走读,BUG主要集中在空指针引起的NullPoin ...

  5. HDU1863 畅通工程---(最小生成树)

    畅通工程 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  6. 【poj3294-不小于k个字符串中最长公共子串】后缀数组

    1.注意每两个串之间的连接符要不一样. 2.分组的时候要注意最后一组啊!又漏了! 3.开数组要考虑连接符的数量.100010是不够的至少要101000. #include<cstdio> ...

  7. [ZOJ2341]Reactor Cooling解题报告|带上下界的网络流|无源汇的可行流

    Reactor Cooling The terrorist group leaded by a well known international terrorist Ben Bladen is bul ...

  8. HDU 1798 Tell me the area (数学)

    题目链接 Problem Description     There are two circles in the plane (shown in the below picture), there ...

  9. Node.js 编码转换

    Node.js自带的toString()方法不支持gbk,因此中文转换的时候需要加载第三方库,推荐以下两个编码转换库,iconv-lite和encoding.       iconv, iconv-l ...

  10. zhudongfangyu.exe进程是360主动防御进程,用来监控电脑系统,防止电脑病毒出现并阻止病毒或木马的安全进程

    zhudongfangyu.exe进程是360主动防御进程,用来监控电脑系统,防止电脑病毒出现并阻止病毒或木马的安全进程