题意:给定一个n个点的图,这个图是一棵树,然后有些点建立了集市。并且没有集市的地方去集市一定是去最近的,如果距离相同,那么则去标号最小的。。现在你还能在建一个集市,问建完这个集市最多有多少个点来这里。。

思路:

现对于每个点求该点到有标记点最近的距离,记录距离及其最近标号,可以用树形dp或者spfa搞。。

然后我们任意选定一个点建树,建完后进行点分治。。

对于当前分治快的跟rt,求rt到每个点的距离为dis,near为到标记点最近的距离

那么对于不同子树的点u,v,如果dis[u] + dis[v] < near[v],那么如果u建立集市v肯定到u。。

那么我们把式子变形下,dis[u] < near[v] - dis[v],对于u直接二分查找统计即可。。

我们可以先不管哪棵子树先统计一边,然后再减去相同的即可,这样写起来方便点。。写起来还蛮像poj1741的。。

code:

 /*
* Author: Yzcstc
* Created Time: 2014/10/2 17:37:34
* File Name: hdu5016.cpp
*/
#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<ctime>
#define repf(i, a, b) for (int i = (a); i <= (b); ++i)
#define repd(i, a, b) for (int i = (a); i >= (b); --i)
#define M0(x) memset(x, 0, sizeof(x))
#define clr(x, y) memset(x, y, sizeof(x))
#define N 120000
#define Inf 0x3fffffff
#define x first
#define y second
using namespace std;
typedef pair<int, int> pii;
struct edge{
int v, w, next;
edge(){}
edge(int _v, int _w, int _next):v(_v), w(_w), next(_next){}
} e[N<<];
int last[N], n, len, have[N], ans[N];
int inq[N];
pii ner[N]; void add(int u, int v, int w){
e[len] = edge(v, w, last[u]), last[u] = len++;
} void init(){
clr(last, -);
len = ;
int u, v, w;
for (int i = ; i < n; ++i){
scanf("%d%d%d", &u, &v, &w);
add(u, v, w), add(v, u, w);
}
repf(i, , n) scanf("%d", &have[i]);
} void gao(){
repf(i, , n) ner[i].x = ner[i].y = Inf, inq[i] = ;
queue<int> q;
repf(i, , n) if (have[i]){
ner[i].x = , ner[i].y = i;
q.push(i), inq[i] = ;
}
int u, v;
pii tmp;
while (!q.empty()){
u = q.front();
q.pop(), inq[u] = ;
for (int p = last[u]; ~p; p = e[p].next){
v = e[p].v;
tmp.x = ner[u].x + e[p].w, tmp.y = ner[u].y;
if (tmp < ner[v]){
ner[v] = tmp;
if (!inq[v]) inq[v] = , q.push(v);
}
}
} }
/*** 点分治-begin **/
int vis[N], sz, msize[N], f[N], size[N], belong[N], ss, ff[N];
int dis[N];
pair<int, int> s[N], tp; void dfs(int u, int fa){ //calculate the size
f[sz++] = u;
msize[u] = , size[u] = ;
int v;
for (int p = last[u]; ~p; p = e[p].next){
v = e[p].v;
if (v == fa || vis[v]) continue;
dfs(v, u);
size[u] += size[v];
msize[u] = max(size[v], msize[u]);
}
} void dfs(int u, int fa, int dist){
dis[u] = dist, ff[ss++] = u;
int v;
for (int p = last[u]; ~p; p = e[p].next){
v = e[p].v;
if (v == fa || vis[v]) continue;
dfs(v, u, dist + e[p].w);
}
} void calculate(int u, int dist){
ss = ;
dfs(u, , dist);
for (int i = ; i < ss; ++i)
s[i].x = ner[ff[i]].x - dis[ff[i]], s[i].y = ner[ff[i]].y;
sort(s, s+ss);
int t;
for (int i = ; i < ss; ++i) if (!have[ff[i]]){
tp.x = dis[ff[i]], tp.y = ff[i];
t = lower_bound(s, s+ss, tp) - s;
ans[ff[i]] += (dist > ) ? (t - ss) : (ss - t);
}
} void dfs(int u){
sz = ;
dfs(u, );
int rt = , tmp, v;
for (int i = ; i < sz; ++i){
tmp = max(msize[f[i]], sz--size[f[i]]);
if (tmp <= (sz>>)) { rt = f[i]; break; }
}
calculate(rt, );
vis[rt] = ;
for (int p = last[rt]; ~p; p = e[p].next){
v = e[p].v;
if (vis[v]) continue;
calculate(v, e[p].w);
dfs(v);
}
}
/**** 点分治-end***/ void solve(){
gao();
M0(vis);
M0(ans);
dfs();
int mx = ;
for (int i = ; i <= n; ++i)
mx = max(ans[i], mx);
printf("%d\n", mx);
} int main(){
// freopen("a.in", "r", stdin);
// freopen("a.out", "w", stdout);
while (scanf("%d", &n) != EOF){
init();
solve();
}
return ;
}

hdu5016的更多相关文章

  1. 【点分治】hdu5016 Mart Master II

    点分治好题. ①手动开栈. ②dp预处理每个点被哪个市场控制,及其距离是多少,记作pair<int,int>数组p. ③设dis[u].first为u到重心s的距离,dis[u].seco ...

  2. Bryce1010 Acm模板

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

随机推荐

  1. hdu 5441 Travel (2015长春网赛)

    http://acm.hdu.edu.cn/showproblem.php?pid=5441 题目大意是给一个n个城市(点)m条路线(边)的双向的路线图,每条路线有时间值(带权图),然后q个询问,每个 ...

  2. hdu 2066 ( 最短路) Floyd & Dijkstra & Spfa

    http://acm.hdu.edu.cn/showproblem.php?pid=2066 今天复习了一下最短路和最小生成树,发现居然闹了个大笑话-----我居然一直写的是Floyd,但我自己一直以 ...

  3. Json数据处理协议与办法

    [JSON学习]     一.概述     JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文 本格式,是理想的数据交换格式.同时,J ...

  4. java集合示例 小心重载的陷阱

    package com.hra.riskprice; import com.hra.riskprice.SysEnum.Factor_Type; import org.springframework. ...

  5. Linux下设置Apache支持Https服务

    HTTPS的主要作用: 1)建立一个信息安全通道,来保证数据传输的安全性 2)确认网站的真实性 HTTPS与HTTP的区别: 1)HTTPS协议需要到ca申请证书,免费证书较少 2)HTTP是超文本传 ...

  6. STL基础2:vector中使用结构体

    #include <iostream> #include <vector> #include <numeric> #include <algorithm> ...

  7. springMVC学习一 工作机制

    springMVC下面的四大组件: (1)DispatcherServlet : 前端控制器,接收所有请求 ,并把请求路径和请求参数解析出来,本质是一个servlet在web.xml中配置 (如果配置 ...

  8. canvas和图片互转

    原文:http://www.jb51.net/html5/160920.html 这么神奇么?先记录一下. 使用JavaScript将图片拷贝进画布 要想将图片放入画布里,我们使用canvas元素的d ...

  9. mysql里几个超时配置参数wait_timeout,net_read_timeout等

    以下这些配置项单位都是秒,在mysql命令行中可以使用show global variables like '变量名';可查询配置值. connect_timeout:连接响应超时时间.服务器端在这个 ...

  10. sqlserver中的CHARINDEX用法

    CHARINDEX作用 写SQL语句我们经常需要判断一个字符串中是否包含另一个字符串,但是SQL SERVER中并没有像C#提供了Contains函数,不过SQL SERVER中提供了一个叫CHAEI ...