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

Problem Description
Trader Dogy lives in city S, which consists of n districts. There are n - 1 bidirectional roads in city S, each connects a pair of districts. Indeed, city S is connected, i.e. people can travel between every pair of districts by roads.



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?
 
Input
There are multiple test cases. Please process till EOF.



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.
 
Output
For each test case, output one number, denotes the number of people you can attract, taking district as a unit.
 
Sample Input
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
 
Sample Output
2
4
0
1
 
Source
2014 ACM/ICPC Asia Regional Xi'an Online

题目解说: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 树分治的更多相关文章

  1. HDU 4871 Shortest-path tree 最短路 + 树分治

    题意: 输入一个带权的无向连通图 定义以顶点\(u\)为根的最短路生成树为: 树上任何点\(v\)到\(u\)的距离都是原图最短的,如果有多条最短路,取字典序最小的那条. 然后询问生成树上恰好包含\( ...

  2. HDU 4812 D Tree 树分治+逆元处理

    D Tree Problem Description   There is a skyscraping tree standing on the playground of Nanjing Unive ...

  3. HDU - 4871 Shortest-path tree (最短路径树+ 树分治)

    题意:给你一张带权无向图,先求出这张图从点1出发的最短路树,再求在树上经过k个节点最长的路径值,以及个数. 分析:首先求最短路树,跑一遍最短路之后dfs一遍即可建出最短路树. 第二个问题,树分治解决. ...

  4. HDU 4812 D Tree 树分治

    题意: 给出一棵树,每个节点上有个权值.要找到一对字典序最小的点对\((u, v)(u < v)\),使得路径\(u \to v\)上所有节点权值的乘积模\(10^6 + 3\)的值为\(k\) ...

  5. 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分

    树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...

  6. 树分治learning

    学习了树的点分治,树的边分治似乎因为复杂度过高而并不出众,于是没学 自己总结了一下 有些时候面对一些树上的结构 并且解决的是和路径有关的问题的时候 如果是多个询问 关注点在每次给出两个点,求一些关于这 ...

  7. hdu-5977 Garden of Eden(树分治)

    题目链接: Garden of Eden Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/ ...

  8. 【BZOJ-1468】Tree 树分治

    1468: Tree Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1025  Solved: 534[Submit][Status][Discuss] ...

  9. BZOJ 2152: 聪聪可可 树分治

    2152: 聪聪可可 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一 ...

随机推荐

  1. 编写自定义的JDBC框架与策略模式

    本篇根据上一篇利用数据库的几种元数据来仿造Apache公司的开源DbUtils工具类集合来编写自己的JDBC框架.也就是说在本篇中很大程度上的代码都和DbUtils中相似,学完本篇后即更容易了解DbU ...

  2. CentOS查看端口是否被占用

    CentOS查看端口是否被占用 本文介绍了linux中查看某一端口是否被占用的方法,有关netstat命令的使用技巧,感兴趣的朋友可以参考下. 使用命令: netstat -tunlp 会显示所有端口 ...

  3. javascript 判断IOS版本号

    先来观察 iOS 的 User-Agent 串: iPhone 4.3.2 系统: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; ...

  4. 能上QQ无法上网

    不少网友碰到过或亲身经历过电脑QQ还在登录,并且还能正常聊天,但是却打不开网站网页的情况,而当电脑出现能上qq但是打不开网页是由什么原因引起,我们又该如何解决类似的电脑故障呢. 适用范围及演示工具 适 ...

  5. python 在 eclipse 上的编码配置问题

    Eclipse的设置 window->preferences->general->editors->text editors->spelling->encoding ...

  6. cPickle.so:: PyUnicodeUCS2_DecodeUTF8

    cPickle.so:: PyUnicodeUCS2_DecodeUTF8错误 Python编译的参数,和Python module(mod_wsgi, pymodwsgi)编译参数不一,导致一些un ...

  7. 查看内存数据的函数(ByteToHex和ByteToBin,最终都变成String)

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  8. html适配Anroid手机

    本文全然是翻译与总结谷歌官方的教程,已确保文档的正确性. 免得大家被五花八门的其它的资料弄混了,也没有系统行的学习. 一.设置窗体尺寸和适配屏幕分辨率 谷歌官方文档提到两个大的方面. 1.Viewpo ...

  9. [Android Studio 权威教程]Windows下安装Android Studio

    从AS 0.5版本号開始使用.也是AS的推行者,在ApkBus公布的第一篇Android Studio Perview 2 获得了50K的浏览,1800多条回复下载. 在我的[Android Stud ...

  10. 4种Delphi IDE的调试时查看内存的方法,太酷了!

    1.ctrl+alt+m,可以查看每个函数过程的内存位置 2.Ctrl+Alt+C 查看代码对应的汇编 3.原来用delphi看变量信息一直是简单的用watch看,但是有时候变量值直接用特定类型看总是 ...