UVA 12161 Ironman Race in Treeland (树分治)
题意:求树上的一条费用不超过m的路径,使得总长度尽量大。
人参第一发树分治,紫书上思路讲得比较清晰,这里不再赘述。
实现的时候,用一个类似时间戟的东西,记录结点首次访问的时间,并保存结点序列。
合并的时候用map组织有序表。和Defense Lines类似
复杂度O(nlog^2n)
#include<bits/stdc++.h>
using namespace std; const int maxn = 3e4+;
int n,m;
int hd[maxn], nx[maxn<<], to[maxn<<], dam[maxn<<], len[maxn<<], ec; inline void add(int u,int v,int D,int L)
{
to[ec] = v;
dam[ec] = D;
len[ec] = L;
nx[ec] = hd[u];
hd[u] = ec++;
} int root, best;
int ct[maxn];
//best = n
void GetBaryCenter(int u,int f)
{
ct[u] = ;
int Mx = ;
for(int i = hd[u]; ~i; i = nx[i]){
if(to[i] != f){
GetBaryCenter(to[i], u);
ct[u] += ct[to[i]];
Mx = max(Mx,ct[to[i]]);
}
}
Mx = max(Mx,n-ct[u]);
if(Mx < best){
best = Mx;
root = u;
}
} #define MP make_pair
#define fi first
#define se second
int C[maxn], L[maxn]; map<int,int> mp;
map<int,int>::iterator it; int ans;
int path[maxn];
int pre[maxn], dfs_clk;
//dfs_clk = 0, ans = 0;
void dfs(int u = root,int f = )
{
path[dfs_clk] = u;
pre[u] = dfs_clk++;
C[u] = ; L[u] = ;
for(int i = hd[u]; ~i; i = nx[i]){
if(to[i] != f){
int v = to[i];
dfs(v,u);
for(int j = pre[v]; j < dfs_clk ; j++){
int x = path[j];
C[x] += dam[i];
L[x] += len[i];
}
}
}
//子树都访问完里以后统一处理以保证互不干扰,这样mp就可以设置为全局变量
mp.clear();
for(int i = hd[u]; ~i; i = nx[i]){
int nex = nx[i];
int lim = ~nex? pre[to[nex]] : dfs_clk;
if(to[i] != f){
int v = to[i];
for(int j = pre[v]; j < lim ; j++){
int x = path[j];
if(C[x] <= m){
ans = max(ans,L[x]);
it = mp.upper_bound(m-C[x]);//找到一个key <= C[x]
if(it != mp.begin()){
ans = max(ans,(--it)->second+L[x]);
}
}
}
for(int j = pre[v]; j < lim ; j++){
int x = path[j];
if(C[x] <= m){
it = mp.lower_bound(C[x]);
bool swc = false;
if(it == mp.begin() || (swc = true , L[x] > (--it)->se) ){
if(swc) it++;
while(it != mp.end() && it->se <= L[x]) mp.erase(it++);
if(it == mp.end() || it->fi > C[x]) {//lower_bound可能使得it指向key == C[x] 而 val >= L[x]
mp.insert(MP(C[x],L[x]));
}
}
}
}
}
}
} //#define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
int T, ks = ; cin>>T;
while(T--){
scanf("%d%d",&n,&m);
memset(hd+,-,sizeof(int)*n); ec = ;
for(int i = n; --i;){
int a,b,D,L; scanf("%d%d%d%d",&a,&b,&D,&L);
add(a,b,D,L); add(b,a,D,L);
}
best = n+;
GetBaryCenter(,);
dfs_clk = ans = ;
dfs();
printf("Case %d: %d\n",++ks,ans);
}
return ;
}
UVA 12161 Ironman Race in Treeland (树分治)的更多相关文章
- UVA 12161 Ironman Race in Treeland
题目大意: 每一条边都有两个权值,val和路径长度d,要保证在val<=m 的条件下,求最长的d. 解题报告: 一开始想错了,后来发现还不如直接暴力点分,思想很套路.. 平时我们统计时,都会用合 ...
- 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] ...
- HDU 4812 D Tree 树分治+逆元处理
D Tree Problem Description There is a skyscraping tree standing on the playground of Nanjing Unive ...
- BZOJ 2152: 聪聪可可 树分治
2152: 聪聪可可 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一 ...
- POJ 1741 Tree 树分治
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...
- UVALive 7148 LRIP【树分治+线段树】
题意就是要求一棵树上的最长不下降序列,同时不下降序列的最小值与最大值不超过D. 做法是树分治+线段树,假设树根是x,y是其当前需要处理的子树,对于子树y,需要处理出两个数组MN,MX,MN[i]表示以 ...
- BZOJ 2566 xmastree(树分治+multiset)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2566 题意:一棵有边权的树.结点有颜色.每次修改一个点的颜色.求每次修改后所有同色 ...
- 树分治&树链剖分相关题目讨论
预备知识 树分治,树链剖分 poj1741 •一棵有n个节点的树,节点之间的边有长度.方方方想知道,有多少个点对距离不超过m 题解 点分治模板题.详见我早上写的http://www.cnblogs ...
随机推荐
- Delphi Runtime Library在哪里?
Delphi Runtime Library是Delphi的运行时库,里面包含了大部分Delphi库的代码,这些库代码在哪里呢?其实正常安装完Dephi之后,在它的安装目录下面!下面我以我的Delph ...
- smix到底是个啥?Perl的正则表达式匹配模式
最近在研究一个perl项目,临时学习了一下perl语法,强行看项目源码.因为总是见到各种正则表达式后面接smxi之类,虽然知道是匹配模式,但脑子里毫无概念.所以特地去学习了一下. 以上为背景. Per ...
- 【转至hejinde的专栏】Axure RP 8最新激活码(可用注册码)
Licensee:米 业成 (STUDENT)Key:nFmqBBvEqdvbiUjy8NZiyWiRSg3yO+PtZ8c9wdwxWse4WprphvSu9sohAdpNnJK5 亲测可用
- Mol Cell Proteomics. |马臻| psims-一个用于编写HUPO-PSI标准下的mzML和mzIdentML的python库
大家好,本周分享的是发表在MCP(MOLECULAR&CRLLULAR PROTEOMICS)上的一篇关于质谱数据处理和识别的文章,题目是psims - A Declarative Write ...
- C#网络编程学习(4)---Socket Tcp进阶之 使用异步循环接收客户端连接和信息
1.方法介绍 BeginAccept(AsyncCallback callback, object state); 异步开始监听客户端连接. callback为一个委托,在成功接收客户端连接时调用委托 ...
- 关于Markdown的一些学习笔记
**关于Markdown的一些学习笔记** 一直利用markdown进行博客的文档编写,一方面是因为不需要特别注重排版,另一方面是十分的方便.最近突发奇想的认为,如果能运用到平时的作业或课程中,会不会 ...
- 手动添加git 到 右键菜单
1.通过在“运行”中输入‘regedit’,打开注册表. 2.找到[HKEY_CLASSES_ROOT\Directory\Background]. 3.在[Background]下如果没有[shel ...
- Codeforces Round #363 (Div. 2) B
Description You are given a description of a depot. It is a rectangular checkered field of n × m siz ...
- Docker从入门到实战(二)
Docker从入门到实战(二) 一:什么是docker Docker是一个开源的应用容器引擎,开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到主流的Linux.MacOS.Windo ...
- 用servlet获取IP等信息
Locale languageType=request.getLocale();//获取用户语言 String localIp=request.getLocalAddr();//获取本地ip int ...