hdu5016
题意:给定一个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的更多相关文章
- 【点分治】hdu5016 Mart Master II
点分治好题. ①手动开栈. ②dp预处理每个点被哪个市场控制,及其距离是多少,记作pair<int,int>数组p. ③设dis[u].first为u到重心s的距离,dis[u].seco ...
- Bryce1010 Acm模板
目录 STL标准模板库 STL简介 STL pair STL set STL vector STL string STL stack STL queue STL map upper_bound和low ...
随机推荐
- iOS.Debug.Simulator
1. iOS Simulator Tips & Tricks http://code.tutsplus.com/tutorials/ios-simulator-tips-tricks--mob ...
- HDU 2255.奔小康赚大钱 最大权匹配
奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- Delphi、Lazarus保留字、关键字详解
Delphi.Lazarus保留字.关键字详解 来自橙子,万一的博客以及其他地方 保留字:变量等标识符可以再使用: 关键字:有特定含义,不能再次重新定义: 修饰字:类似保留字的功能,也就是说可以重用 ...
- ListView item中有button或EditText时 点击事件失效问题的解决
加入:android:descendantFocusability="blocksDescendants" 代码如下: <LinearLayout xmlns:android ...
- spring boot所有配置
转载 http://blog.csdn.net/lpfsuperman/article/details/78287265 # 日志配置# 日志配置文件的位置. 例如对于Logback的`classpa ...
- 关于SSH中tomcat下中文名称图片不显示的问题
最近做一个SSH框架的项目,用tomcat发布,需要上传图片到指定路径,然后再将图片显示在页面上.有一个问题:如果是英文名称的图片,就正常显示,可如果是中文的,它就是显示不出来,于是乎,在网上各种百度 ...
- 查看Android应用所需权限(uses-permission)
http://www.tuicool.com/articles/zq2meq MainActivity如下: package cc.testusespermission; import android ...
- 使用xtrabackup备份innodb引擎的数据库
innodb引擎的数据库可以使用mysqldump备份,如果表很大几十个G甚至上百G,显示用mysqldump备份会非常慢.然后使用xtrabackup 可以很快的在线备份innodb数据库.Inno ...
- Java第1章笔记
第一章 计算机程序:计算机为完成某些功能产生的一系列有序指令集合. Java技术包括:JavaSE(标准版) JavaEE(企业版) ---JavaME(移动版) 开发Java程序步骤:1.编写 2 ...
- python学习 day7 (3月8日)
read()读出来了之后文件里就从之后开始 光标不知道在哪 编码的进阶: 背景: ASCII:英文字母,数字,特殊符号,------------>二进制的对应关系 str: 一个字符 ---- ...