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.Operation-on-ZipFile
Operation on ZipFile Reference 在Mac OS X和iOS中操作.zip文件(例如创建zip文件, 从zip文件中抽取数据): 1. http://stackoverfl ...
- linux网卡绑定脚本
2013-08-20 15:30:51 此脚本适用于CentOS5.x和CentOS6.x. #!/bin/bash #**************************************** ...
- [FreeMind] 绘制思维时遇到的常见问题解决办法
如何改变节点的摆放方向? 如果是新建节点,选择要放置节点的那一侧,按enter键,或者鼠标右键,插入平行节点即可. 如果是已经建好的节点,可以用ctrl+x, ctrl+v粘贴到另一边,或者选中子节点 ...
- Python之路(第七篇)Python作用域、匿名函数、函数式编程、map函数、filter函数、reduce函数
一.作用域 return 可以返回任意值例子 def test1(): print("test1") def test(): print("test") ret ...
- SSH无法连上CentOS7的问题
今天安装完带GNOME的CentOS后发现XShell无法连接上Linux. 原因是sshd服务没有开启.下面是解决办法: 1 ip addr 发现网卡名称为ens33 2 在/etc/sysconf ...
- c++智能指针(1)
根据muduo开源库作者陈硕的一些文章.对于多线程下C++编程提出了一些观点.主要是多线程下对象的销毁比较困难,但是由于多线程下,mutext是无法保护析构的.而后提出了智能指针的方案并对使用该指针会 ...
- 【Java】JABX实现对象与XML互转
JABX简介 JAXB能够使用Jackson对JAXB注解的支持实现(jackson-module-jaxb-annotations),既方便生成XML,也方便生成JSON,这样一来可以更好的标志可以 ...
- ORACLE rollup函数
rollup函数应用场景: 主要使用在 分组中,将每个分组求汇总值(就是小计),最后再讲所有值(除去小计)求和(就是合计) 当然,使用union 也可以达到同样的效果.先将需要查询的分组查出来,再un ...
- 对象序列化:pickle和shelve
import pickle class DVD: def __init__(self,tilte,year=None,duration=None,director_id=None): self.tit ...
- string流
istringstream和ostringstream 从istringstream类中读取数据赋值给某个string,写入某个string到ostringstream类,头文件<sstream ...