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 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一 ...
随机推荐
- ios开发者创建app应用开发授权文件 实战方法:
收到apple邮件成为合法的开发者后,进入https://developer.apple.com/account/ios/profile/profileList.action页面 总的有4步操作: 1 ...
- AFNetwork学习(二)——GET/POST请求
为了学习AFNetwork,自己搭建整理了一下AFNetwork向后台发送请求和后台返回json数据的整个处理过程.利用Struts2搭建了一个后台,提供Action并返回json数据 环境:Xcod ...
- 6月19日 NSFileHandle文件类的常用方法
NSFileManager类主要对文件的操作(删除,修改,移动,复制等): NSFileHandle类主要对文件内容进行读取和写入操作 NSFileHandle处理文件的步骤 ...
- Servlet的学习之Response响应对象(1)
在之前学习了Servlet中的主体结构,包括Servlet的生命周期方法,和非生命周期方法能获取的一些非常重要的对象如ServletConfig.ServletContext对象等,而从这篇开始我们将 ...
- hdu 4687 Boke and Tsukkomi
Dancing link twice. Find the maximum combination numbers in the first time. Enumerate each node, dan ...
- Qt之设置QWidget背景色(QStyleOption->drawPrimitive(QStyle::PE_Widget)方法比较有趣)
QWidget是所有用户界面对象的基类,这意味着可以用同样的方法为其它子类控件改变背景颜色. Qt中窗口背景的设置,下面介绍三种方法. 1.使用QPalette2.使用Style Sheet3.绘图事 ...
- oracle系统包——dbms_random用法及order by 小结(转)
dbms_random是一个可以生成随机数值或者字符串的程序包. 这个包有initialize().seed().terminate().value().normal().random().strin ...
- win7下让程序默认以管理员身份运行
在win7中用自己写的程序读取MBR时,突然提示无法对磁盘进行操作,而在xp下并没有这个问题:最后点右键以管理员身份运行才可以正常运行.于是想办法让程序在双击启动时默认以管理员身份运行.具体方法: 1 ...
- Hongwei Xi
Hongwei Xi Hongwei Xi Hongwei Xi's Curriculum Vita Hongwei Xi
- Android RingtoneManager铃声管理
本篇介绍一下跳转到系统铃声选择界面,android中的铃声通过RingtoneManager管理,RingtoneManager管理来电铃声(TYPE_RINGTONE).提示音(TYPE_NOTIF ...