HDU 4916 树分治
Mart Master II
Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 285 Accepted Submission(s): 94
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.
5
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
2
4
0
1
题目解说:http://www.itnose.net/detail/6118094.html
代码:
/* ***********************************************
Author :rabbit
Created Time :2014/11/1 22:13:28
File Name :6.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
const int maxn=100100;
struct Edge{
int next,to,w;
}edge[maxn*2];
int head[maxn],tot;
void init(){
tot=0;
memset(head,-1,sizeof(head));
}
inline void addedge(int u,int v,int w){
edge[tot].to=v;
edge[tot].next=head[u];
edge[tot].w=w;
head[u]=tot++;
}
int size[maxn],vis[maxn],fa[maxn],que[maxn];
int TT;
inline int getroot(int u){
int Min=maxn,root=0;
int l,r;
que[l=r=1]=u;
fa[u]=0;
for(;l<=r;l++)
for(int i=head[que[l]];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(v==fa[que[l]]||vis[v]==TT)continue;
que[++r]=v;
fa[v]=que[l];
}
for(l--;l;l--){
int x=que[l],Max=0;
size[x]=1;
for(int i=head[x];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(v==fa[x]||vis[v]==TT)continue;
Max=max(Max,size[v]);
size[x]+=size[v];
}
Max=max(Max,r-size[x]);
if(Max<Min){
Min=Max;root=x;
}
}
return root;
}
int ans[maxn];
pair<int,int> pp[maxn],np[maxn];
int dis[maxn],type[maxn];
inline void go(int u,int pre,int w,int tt){
int l,r;
que[l=r=1]=u;
fa[u]=pre;dis[u]=w;
for(;l<=r;l++)
for(int i=head[que[l]];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(v==fa[que[l]]||vis[v]==TT)continue;
que[++r]=v;
fa[v]=que[l];
dis[v]=dis[que[l]]+edge[i].w;
}
int cnt=0;
for(int i=1;i<=r;i++){
int x=que[i];
pp[cnt++]=make_pair(np[x].first-dis[x],np[x].second);
}
sort(pp,pp+cnt);
for(int i=1;i<=r;i++){
int x=que[i];
if(type[x])continue;
int id=lower_bound(pp,pp+cnt,make_pair(dis[x],x))-pp;
ans[x]+=(cnt-id)*tt;
}
}
void solve(int u){
int root=getroot(u);
vis[root]=TT;
go(root,0,0,1);
for(int i=head[root];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(vis[v]==TT)continue;
go(v,root,edge[i].w,-1);
}
for(int i=head[root];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(vis[v]==TT)continue;
solve(v);
}
}
bool ff[maxn];
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
int n;
memset(vis,0,sizeof(vis));
TT=0;
while(~scanf("%d",&n)){
init();
int u,v,w;
for(int i=1;i<n;i++){
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
for(int i=1;i<=n;i++)scanf("%d",&type[i]);
queue<int> q;
for(int i=1;i<=n;i++)
if(type[i]){
np[i]=make_pair(0,i);
ff[i]=true;
q.push(i);
}
else {
np[i]=make_pair(INF,0);
ff[i]=false;
}
while(!q.empty()){
int u=q.front();
q.pop();
ff[u]=0;
for(int i=head[u];i!=-1;i=edge[i].next){
v=edge[i].to;
pair<int,int> tmp=make_pair(np[u].first+edge[i].w,np[u].second);
if(tmp<np[v]){
np[v]=tmp;
if(!ff[v]){
ff[v]=1;
q.push(v);
}
}
}
}
TT++;
for(int i=1;i<=n;i++)ans[i]=0;
solve(1);
int ret=0;
for(int i=1;i<=n;i++)ret=max(ret,ans[i]);
cout<<ret<<endl;
}
return 0;
}
HDU 4916 树分治的更多相关文章
- HDU 4871 Shortest-path tree 最短路 + 树分治
题意: 输入一个带权的无向连通图 定义以顶点\(u\)为根的最短路生成树为: 树上任何点\(v\)到\(u\)的距离都是原图最短的,如果有多条最短路,取字典序最小的那条. 然后询问生成树上恰好包含\( ...
- HDU 4812 D Tree 树分治+逆元处理
D Tree Problem Description There is a skyscraping tree standing on the playground of Nanjing Unive ...
- HDU - 4871 Shortest-path tree (最短路径树+ 树分治)
题意:给你一张带权无向图,先求出这张图从点1出发的最短路树,再求在树上经过k个节点最长的路径值,以及个数. 分析:首先求最短路树,跑一遍最短路之后dfs一遍即可建出最短路树. 第二个问题,树分治解决. ...
- HDU 4812 D Tree 树分治
题意: 给出一棵树,每个节点上有个权值.要找到一对字典序最小的点对\((u, v)(u < v)\),使得路径\(u \to v\)上所有节点权值的乘积模\(10^6 + 3\)的值为\(k\) ...
- 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分
树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...
- 树分治learning
学习了树的点分治,树的边分治似乎因为复杂度过高而并不出众,于是没学 自己总结了一下 有些时候面对一些树上的结构 并且解决的是和路径有关的问题的时候 如果是多个询问 关注点在每次给出两个点,求一些关于这 ...
- hdu-5977 Garden of Eden(树分治)
题目链接: Garden of Eden Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/ ...
- 【BZOJ-1468】Tree 树分治
1468: Tree Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1025 Solved: 534[Submit][Status][Discuss] ...
- BZOJ 2152: 聪聪可可 树分治
2152: 聪聪可可 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一 ...
随机推荐
- 关于new enhancement的一些知识
关于new enhancement sap源程序里也给我们留了很多. 以下例句point .section.spot说明这些知识点. 1.不管是point还是section 都是基于spot的,spo ...
- Android 带你从源码的角度解析Scroller的滚动实现原理
转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17483273),请尊重他人的辛勤劳动成果,谢谢! 今天给大 ...
- 将 Shiro 作为一个许可为基础的应用程序 五:password加密/解密Spring应用
考虑系统password的安全,眼下大多数系统都不会把password以明文的形式存放到数据库中. 一把会採取下面几种方式对password进行处理 password的存储 "编码" ...
- 显示出eclipse文件层次
看到图片中右边那个倒三角型符号没, 点一下,弹出个菜单,选package presentation->hierarachial 文件目录结构 flat 是包结构
- 输出特殊符号,可以用单引号'引文':echo 'Hello World !'
输出特殊符号,可以用单引号'引文':echo 'Hello World !'
- VS2010 编译安装boost库
实践是最好的办法..学习C++,想试试线程,然后打算用boost库,结果boost库编译差点吓到我..没看到比较完整的安装教程..一直耽搁.今天动手.完成了.方法记录如下:1.下载boost从boos ...
- openfire学习4------->android客户端聊天开发之聊天功能开发
前面我们已经把服务器搭建完成,并且在客户端实现了登录了. 和我们使用的QQ一样,想一想,登录成功之后呢?肯定是要有一个好友列表,通过这个列表,我们可以选择我们需要聊天的好友. 这里我们先研究下 xmp ...
- Lucene.Net 2.3.1开发介绍 —— 四、搜索(三)
原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(三) Lucene有表达式就有运算符,而运算符使用起来确实很方便,但另外一个问题来了. 代码 4.3.4.1 Analyzer anal ...
- getResource(String name)用法及源码分析
Project获取资源需要一个启点,加载资源的动作是由ClassLoader来完成的.Class对象和当前线程对象可以找到当前加载资源的ClassLoader,通过ClassLoader的getRes ...
- 让自己的软件实现拖拽打开文件(使用WM_DROPFILES消息和DragQueryFile函数)
//声明 protected procedure WMDROPFILES(var Msg : TMessage); message WM_DROPFILES; //实现 procedure TForm ...