SP1825 FTOUR2 - Free tour II 点分治+启发式合并+未调完
题意翻译
给定一棵n个点的树,树上有m个黑点,求出一条路径,使得这条路径经过的黑点数小于等于k,且路径长度最大
Code:
#include <bits/stdc++.h>
using namespace std;
#define pr pair<int, int>
#define mp make_pair
const int maxn = 2000003;
const int inf = 1000000000;
void setIO(string a)
{
string in = a + ".in", out = a + ".out";
freopen(in.c_str(), "r", stdin);
}
vector <pr> vrr;
int edges, n, m, K, ans, mdep, tl, root = 0, sn;
int hd[maxn], to[maxn << 1], nex[maxn << 1], val[maxn << 1], siz[maxn];
int mk[maxn], vis[maxn], mine[maxn], dis[maxn], tmp1[maxn], tmp2[maxn], f[maxn];
void add(int u, int v, int c)
{
nex[++edges] = hd[u], hd[u] = edges, to[edges] = v, val[edges] = c;
}
void Getroot(int u, int ff)
{
siz[u] = 1, f[u] = 0;
for(int i = hd[u]; i ; i = nex[i])
{
int v = to[i];
if(v == ff || vis[v]) continue;
Getroot(v, u);
siz[u] += siz[v], f[u] = max(f[u], siz[v]);
}
f[u] = max(sn - siz[u], f[u]);
if(f[u] < f[root]) root = u;
}
void getmax(int x, int ff, int d1)
{
siz[x]=1;
mdep = max(mdep, d1 + mk[x]);
for(int i = hd[x]; i ; i = nex[i])
{
int v = to[i];
if(vis[v] || v == ff) continue;
dis[v] = dis[x] + val[i];
getmax(v, x, d1 + mk[x]);
siz[x]+=siz[v];
}
}
void getdis(int x, int ff, int d2)
{
if(d2 > K) return ;
tmp1[++tl] = dis[x], tmp2[tl] = d2 + mk[x];
for(int i = hd[x]; i ; i = nex[i])
{
int v = to[i];
if(v == ff || vis[v]) continue;
getdis(v, x, d2 + mk[x]);
}
}
void calc(int x)
{
if(mk[x]) --K;
vrr.clear();
siz[x]=1;
for(int i = hd[x]; i ; i = nex[i])
{
int v = to[i];
if(vis[v]) continue;
mdep = 0, dis[v] = val[i];
getmax(v, x, 0);
siz[x]+=siz[v];
vrr.push_back(mp(mdep, v));
}
sort(vrr.begin(), vrr.end());
tl = mine[0] = 0;
// printf("%d ::: ",x);
for(int sz = vrr.size(), i = 0; i < sz; ++i)
{
int cur = vrr[i].second;
int pdl = tl;
getdis(cur, x, 0);
for(int j = pdl + 1; j <= tl; ++j)
if(K >= tmp2[j])
ans = max(ans, mine[K - tmp2[j]] + tmp1[j]);
// printf("%d ",vrr[i].second);
// tmp2[j] :: 有tmp2[j]个黑子时的最大值.
for(int j = pdl + 1; j <= tl; ++j) mine[tmp2[j]] = max(mine[tmp2[j]], tmp1[j]);
for(int j = 1; j <= vrr[i].first; ++j) mine[j] = max(mine[j-1],mine[j]);
}
// printf("\n");
if(vrr.size())
for(int i=1;i<=vrr[vrr.size()-1].first;++i) mine[i] = -inf;
if(mk[x]) ++K;
}
void solve(int u)
{
vis[u] = 1;
calc(u);
for(int i=hd[u];i;i=nex[i])
{
int v=to[i];
if(vis[v]) continue;
root=0,sn=siz[v];
Getroot(v,u);
solve(root);
}
}
int main()
{
// setIO("input");
scanf("%d%d%d",&n, &K, &m);
for(int i = 1,o; i <= m ; ++i)
{
scanf("%d",&o);
mk[o] = 1;
}
for(int i = 1; i < n ; ++i)
{
int u, v, c;
scanf("%d%d%d",&u, &v, &c);
add(u, v, c), add(v, u, c);
}
for(int i=1;i<maxn;++i) mine[i]=-inf;
sn = n, f[0] = inf;
Getroot(1, 0); solve(root);
printf("%d\n",ans);
return 0;
}
SP1825 FTOUR2 - Free tour II 点分治+启发式合并+未调完的更多相关文章
- [spoj] FTOUR2 FREE TOUR II || 树分治
原题 给出一颗有n个点的树,其中有M个点是拥挤的,请选出一条最多包含k个拥挤的点的路径使得经过的权值和最大. 正常树分治,每次处理路径,更新答案. 计算每棵子树的deep(本题以经过拥挤节点个数作为d ...
- SPOJ:Free tour II (树分治+启发式合并)
After the success of 2nd anniversary (take a look at problem FTOUR for more details), this 3rd year, ...
- FTOUR2 - Free tour II
传送门 题目翻译的很清楚……似乎点分治的题题目描述都非常简洁. 还是那个操作,一条路径要么全部在一棵子树中,要么经过当前的重心,所以考虑点分治. 首先dfs求出重心的每一棵子树中,有i个黑点的最长路径 ...
- SPOJ Free TourII(点分治+启发式合并)
After the success of 2nd anniversary (take a look at problem FTOUR for more details), this 3rd year, ...
- SP1825 【FTOUR2 - Free tour II】
# \(SP1825\) 看到没有人用老师的办法,于是自己写一下思路 思路第一步:排除旧方法 首先这道题和\(4178\)不一样,因为那道题是计数,而这道题是求最值,最值有个坏处,就是对于来自相同子树 ...
- SPOJ1825 FTOUR2 - Free tour II
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- SPOJ FTOUR2 - Free tour II
Description 有些黑点,问你选择不超过 \(k\) 个黑点的路径,路径权值最大是多少. Sol 点分治. 这是qzc的论文题,不过我感觉他的翻译好强啊...我还是选择了自己去看题目... 点 ...
- SPOJ 1825 Free tour II 树分治
题意: 给出一颗边带权的数,树上的点有黑色和白色.求一条长度最大且黑色节点不超过k个的最长路径,输出最长的长度. 分析: 说一下题目的坑点: 定义递归函数的前面要加inline,否则会RE.不知道这是 ...
- spoj 1825 Free tour II
http://www.spoj.com/problems/FTOUR2/ After the success of 2nd anniversary (take a look at problem FT ...
随机推荐
- G - Power Strings
Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc&quo ...
- 树 (p155, 从中序和后续回复二叉树)
递归求解, You are to determine the value of the leaf node in a given binary tree that is the terminal no ...
- JQuery获取select选中值和清除选中状态(转)
1.获取值 var provinceSearch = $("#loc_province_search").find("option:selected").att ...
- GDB 调试 PHP文件
http://www.bo56.com/%E5%9C%A82016%E7%9A%84phpcon%E5%A4%A7%E4%BC%9A%E4%B8%8A%E7%9A%84%E5%88%86%E4%BA% ...
- HDU 4504
直接DP求组合数即可. #include <iostream> #include <cstdio> #include <algorithm> #include &l ...
- Linux下安装lvs
lvs已经编译到linux内核中,仅仅须要安装lvs的管理软件ipvsadm就可以 1. 插入光盘.查找设备 [root@chen ~]# ls -l /dev | grep cdrom lrwxrw ...
- 【转】shell中的内建命令, 函数和外部命令
原文:http://www.cnblogs.com/xkfz007/archive/2011/10/13/2209571.html linux命令有内部命令和外部命令之分.内部命令实际上是shell程 ...
- 动态配置 JBOSS ( eap 6.2 ) 数据源
操作环境 windows + jboss eap 6.2 + MyEclipse 10.0 项目用的是jboss eap 6.2,作为Red公司升级后的eap稳定版. 相比之前的 AS 系列,不管是安 ...
- android 通用菜单条实现(一)
一.前言介绍 直奔主题啦,非常多Android app都有菜单条.菜单条除了背景图片.图标的不同外,布局基本一致.大致能够分为三部分:菜单条的左側区域.菜单条中间区域.菜单条右側区域. 为了考虑代码的 ...
- 【Nginx】模块化设计
高度模块化的设计是Nginx的架构基础.全部模块都是以ngx_module_t结构体表示,该结构体内部定义了7个回调方法.它们负责模块的初始化和退出.commands成员是一个包括有ngx_comma ...