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)
Total Submission(s): 675 Accepted Submission(s): 237
In some districts there are marts founded by Dogy’s competitors. when people go to marts, they’ll choose the nearest one. In cases there are more than one nearest marts, they’ll choose the one with minimal city number.
Dogy’s money could support him to build only one new marts, he wants to attract as many people as possible, that is, to build his marts in some way that maximize the number of people who will choose his mart as favorite. Could you help him?
In each test case:
First line: an integer n indicating the number of districts.
Next n - 1 lines: each contains three numbers bi, ei and wi, (1 ≤ bi,ei ≤ n,1 ≤ wi ≤ 10000), indicates that there’s one road connecting city bi and ei, and its length is wi.
Last line : n(1 ≤ n ≤ 105) numbers, each number is either 0 or 1, i-th number is 1 indicates that the i-th district has mart in the beginning and vice versa.
1 2 1
2 3 1
3 4 1
4 5 1
1 0 0 0 1
5
1 2 1
2 3 1
3 4 1
4 5 1
1 0 0 0 0
1
1
1
0
4
0
1
/*
hdu 5016 点分治(2014 ACM/ICPC Asia Regional Xi'an Online) problem:
有n个城市,有的城市有集市. 城市会选择离他最近,编号最小的集市. 如果再建一个集市,那么最多有多少个城市会来这 solve:
如果 城市v的人要到新的集市u 那么dis(u,v) < dis(v,z).(z为原先离v最近的集市)
所以可以先用最短路求出所有城市的最近集市的距离和编号.
如果用dis表示到根节点的距离,那么 dis[u] + dis[v] < spfa(v,z) ----> dis[u] < dis[v]-spfa(v,z)
所以就成了:求对u而言满足这个公式的点的个数. hhh-2016-08-24 16:17:48
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <math.h>
#include <queue>
#include <map>
#define lson i<<1
#define rson i<<1|1
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define scanfi(a) scanf("%d",&a)
#define scanfl(a) scanf("%I64d",&a)
#define key_val ch[ch[root][1]][0]
#define inf 0x3f3f3f3f
#define mod 1000003
using namespace std;
const int maxn = 100010;
int head[maxn];
int n,k,s[maxn],f[maxn],root,is[maxn];
int Size,tot,u,v,w;
bool vis[maxn];
ll ans[maxn];
ll finans = 0;
ll val;
struct node
{
int to,w;
int next;
} edge[maxn << 2]; void ini()
{
clr(head,-1);
clr(s,0),clr(ans,0);
tot = 0;
} void add_edge(int u,int v,int w)
{
edge[tot].to = v,edge[tot].w = w,edge[tot].next = head[u],head[u] = tot++;
}
pair<int,int> tp[maxn]; void spfa()
{
memset(vis,0,sizeof(vis));
queue<int>q;
for(int i =1; i <= n; i++)
{
if(is[i])
{
tp[i] = make_pair(0,i);
vis[i] = 1;
q.push(i);
}
else
{
tp[i] = make_pair(inf,i);
}
}
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = 0;
for(int i = head[u]; ~i ; i = edge[i].next)
{
int v = edge[i].to;
if(tp[v].first > tp[u].first + edge[i].w)
{
tp[v].first = tp[u].first + edge[i].w;
tp[v].second = tp[u].second;
if(!vis[v])
{
vis[v] = 1;
q.push(v);
}
}
}
}
} void get_root(int now,int fa)
{
int v;
s[now] = 1,f[now] = 0;
for(int i = head[now]; ~i; i = edge[i].next)
{
if((v=edge[i].to) == fa || vis[v])
continue;
get_root(v,now);
s[now] += s[v];
f[now] = max(f[now],s[v]);
}
f[now] = max(f[now],Size-s[now]);
if(f[now] < f[root]) root = now;
}
int num;
int seq[maxn];
int d[maxn];
void dfs(int now,int fa)
{
int v;
seq[num++] = now;
s[now] = 1; for(int i = head[now]; ~i; i = edge[i].next)
{
// cout << edge[i].to << " " <<vis[edge[i].to]<<" " << fa <<endl;
if( (v=edge[i].to) == fa || vis[v])
continue;
d[v] = d[now] + edge[i].w;
dfs(v,now);
s[now] += s[v];
}
}
pair<int,int>t[maxn];
void cal(int now,int ob)
{
num = 0;
d[now] = ob;
dfs(now,0);
// cout <<"root:" << now <<endl;
for(int i=0; i < num; i++)
{
// cout << tp[seq[i]].first-d[seq[i]] << " ";
t[i] = make_pair(tp[seq[i]].first-d[seq[i]],tp[seq[i]].second);
}
// cout <<endl;
// for(int i = 0;i < num ;i++)
// {
// cout << d[seq[i]] << " ";
// }
// cout <<endl;
sort(t,t+num); for(int i = 0; i < num; i++)
{
if(is[seq[i]])
continue;
pair<int,int> temp = make_pair(d[seq[i]],seq[i]);
int pos = lower_bound(t,t+num,temp)-t;
// cout << num <<" " <<pos <<endl;
if(!ob)
ans[seq[i]] += (ll)(num - pos);
else
ans[seq[i]] += (ll)(pos - num);
}
} void make_ans(int now,int cnt)
{
int v ;
f[0] = Size = cnt;
get_root(now,root = 0); cal(root,0);
vis[root] = 1;
for(int i = head[root]; ~i ; i = edge[i].next)
{
if( vis[v = edge[i].to] )
continue;
cal(v,edge[i].w);
make_ans(v,s[v]);
}
} int main()
{
// freopen("in.txt","r",stdin);
while( scanfi(n) != EOF)
{
ini();
finans = 0;
for(int i = 1; i < n; i++)
{
scanfi(u),scanfi(v),scanfi(w);
add_edge(u,v,w);
add_edge(v,u,w);
}
for(int i =1; i<= n; i++)
scanfi(is[i]);
spfa();
// for(int i = 1;i <= n;i++)
// {
// printf("%d %d\n",tp[i].first,tp[i].second);
// }
memset(vis,0,sizeof(vis));
make_ans(1,n);
for(int i = 1;i <=n;i++)
{
finans = max(finans,ans[i]);
}
// cout <<"ans";
printf("%I64d\n",finans);
}
return 0;
}
hdu 5016 点分治(2014 ACM/ICPC Asia Regional Xi'an Online)的更多相关文章
- HDU 5010 Get the Nut(2014 ACM/ICPC Asia Regional Xi'an Online)
思路:广搜, 因为空格加上动物最多只有32个那么对这32个进行编号,就能可以用一个数字来表示状态了,因为只有 ‘P’ 'S' 'M' '.' 那么就可以用4进制刚好可以用64位表示. 接下去每次就 ...
- 2014 ACM/ICPC Asia Regional Xi'an Online(HDU 5007 ~ HDU 5017)
题目链接 A题:(字符串查找,水题) 题意 :输入字符串,如果字符串中包含“ Apple”, “iPhone”, “iPod”, “iPad” 就输出 “MAI MAI MAI!”,如果出现 “Son ...
- 2014 ACM/ICPC Asia Regional Xi'an Online
03 hdu5009 状态转移方程很好想,dp[i] = min(dp[j]+o[j~i]^2,dp[i]) ,o[j~i]表示从j到i颜色的种数. 普通的O(n*n)是会超时的,可以想到o[]最大为 ...
- 2014 ACM/ICPC Asia Regional Xi'an Online Paint Pearls
传说的SB DP: 题目 Problem Description Lee has a string of n pearls. In the beginning, all the pearls have ...
- HDU 5000 2014 ACM/ICPC Asia Regional Anshan Online DP
Clone Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/65536K (Java/Other) Total Submiss ...
- HDU 5029 Relief grain(离线+线段树+启发式合并)(2014 ACM/ICPC Asia Regional Guangzhou Online)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5029 Problem Description The soil is cracking up beca ...
- HDU 5002 Tree(动态树LCT)(2014 ACM/ICPC Asia Regional Anshan Online)
Problem Description You are given a tree with N nodes which are numbered by integers 1..N. Each node ...
- HDU 5000 Clone(离散数学+DP)(2014 ACM/ICPC Asia Regional Anshan Online)
Problem Description After eating food from Chernobyl, DRD got a super power: he could clone himself ...
- HDU 5052 Yaoge’s maximum profit 光秃秃的树链拆分 2014 ACM/ICPC Asia Regional Shanghai Online
意甲冠军: 特定n小点的树权. 以下n每一行给出了正确的一点点来表达一个销售点每只鸡价格的格 以下n-1行给出了树的侧 以下Q操作 Q行 u, v, val 从u走v,程中能够买一个鸡腿,然后到后面卖 ...
随机推荐
- 1013团队Beta冲刺day3
项目进展 李明皇 今天解决的进度 完善了程序的运行逻辑(消息提示框等) 明天安排 前后端联动调试 林翔 今天解决的进度 向微信官方申请登录验证session以维护登录态 明天安排 继续完成维护登录态 ...
- 使用SecureCRTP 连接生产环境的web服务器和数据库服务器
一.使用SecureCRTP 连接生产环境的web服务器 首先,需要知道以下参数信息: 1.web服务器的ip地址 2.服务器的端口号 3.会话连接的用户名和密码 4.服务器的用户名 ...
- python 3.x 爬虫基础---常用第三方库(requests,BeautifulSoup4,selenium,lxml )
python 3.x 爬虫基础 python 3.x 爬虫基础---http headers详解 python 3.x 爬虫基础---Urllib详解 python 3.x 爬虫基础---常用第三方库 ...
- 20170222==(MODBUS读取多个寄存器)
MODBUS读取多个寄存器(功能码04) 为了简单我这里只用4个寄存器,当让你也可以用125个寄存器,但是最多也只能用125个寄存器的.每个寄存器有上面的表知道为一个字的大小即2个字节或者叫16比特位 ...
- GIT入门笔记(15)- 链接到私有GitLab仓库
GitLab是利用 Ruby on Rails 一个开源的版本管理系统,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目.它拥有与Github类似的功能,能够浏览源代码,管理 ...
- (java基础)Java输入输出流及文件相关
字节流: 所有的字节输入输出都继承自InputStream和OutputStream,通常用于读取二进制数据,最基本单位为单个字节,如图像和声音.默认不使用缓冲区. FileInputStream和F ...
- Python学习之list有序集合
# coding=utf-8 # list有序集合 classmate = ['Michael', 'Bob', 'Tracy'] print classmate print len(classmat ...
- Python基础数据类型之int、bool、str
数据类型:int bool str list 元祖 dict 集合 int:整数型,用于各种数学运算. bool:只有两种,True和False,用户判断. str:存储少量数据,进行操作 ...
- centos7搭建nexus maven私服(二)
本文主要补充两个主题: 1.手动更新索引 2.通过maven客户端发布本地jar包到nexus 先说第一个主题: 由于maven中央仓库汇集了全世界绝大多数的组件,所以它的索引库非常庞大,在我们右击仓 ...
- [SHOI2009] 会场预约 - Treap
Description PP大厦有一间空的礼堂,可以为企业或者单位提供会议场地.这些会议中的大多数都需要连续几天的时间(个别的可能只需要一天),不过场地只有一个,所以不同的会议的时间申请不能够冲突.也 ...