spoj 1825 Free tour II
http://www.spoj.com/problems/FTOUR2/
After the success of 2nd anniversary (take a look at problem FTOUR for more details), this 3rd year, Travel Agent SPOJ goes on with another discount tour.
The tour will be held on ICPC island, a miraculous one on the Pacific Ocean. We list N places (indexed from 1 to N) where the visitors can have a trip. Each road connecting them has an interest value, and this value can be negative(if there is nothing interesting to view there). Simply, these N places along with the roads connecting them form atree structure. We will choose two places as the departure and destination of the tour.
Since September is the festival season of local inhabitants, some places are extremely crowded (we call themcrowded places). Therefore, the organizer of the excursion hopes the tour will visit at most K crowded places (too tiring to visit many of them) and of course, the total number of interesting value should be maximum.
Briefly, you are given a map of N places, an integer K, and M id numbers of crowded place. Please help us to find the optimal tour. Note that we can visit each place only once (or our customers easily feel bored), also the departure and destination places don't need to be different.
Input
There is exactly one case. First one line, containing 3 integers N K M, with 1 <= N <= 200000, 0 <= K <= M, 0 <= M <=N.
Next M lines, each line includes an id number of a crowded place.
The last (N - 1) lines describe (N - 1) two-way roads connected N places, form a b i, with a, b is the id of 2 places, and i is its interest value (-10000 <= i <= 10000).
Output
Only one number, the maximum total interest value we can obtain.
Example
Input:
8 2 3
3
5
7
1 3 1
2 3 10
3 4 -2
4 5 -1
5 7 6
5 6 5
4 8 3 Output:
12 题意:n个点的一棵树,有m个黑点,问最多经过k个黑点的最长路径
点分治+启发式合并
对于每一个次的根节点,枚举计算每个孩子的子树中最多有几个黑点
注意当黑点数>k时,及时return k
按黑点数从小到大排序,
对于每个子树
计算子树中经过i个黑点的最长路径dis[i]
同时维护一个数组f,表示前i-1个孩子的各自子树内,经过黑点数<=j的最长路径
枚举这个子树经过多少个黑点,更新答案
有可能最长路就是子树内一个点与根节点之间,所以在计算dis[i]时,也要更新答案 具体看漆子超神犇的论文 为什么时间复杂度是nlogn呐?
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 200002
using namespace std;
int n,k,m,root,ans,max_black,all;
bool crowd[N],vis[N];
int tot,front[N],nxt[N<<],to[N<<],val[N<<];
int siz[N],big[N];
int dis[N],f[N];
struct node
{
int black,id,d;
}e[N];
void read(int &x)
{
x=; int f=; char c=getchar();
while(!isdigit(c)) { if(c=='-') f=-; c=getchar(); }
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
x*=f;
}
void add(int u,int v,int w)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; val[tot]=w;
to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; val[tot]=w;
}
void getroot(int x,int fa)
{
siz[x]=; big[x]=;
for(int i=front[x];i;i=nxt[i])
{
if(vis[to[i]] || to[i]==fa) continue;
getroot(to[i],x);
siz[x]+=siz[to[i]];
big[x]=max(big[x],siz[to[i]]);
}
big[x]=max(big[x],all-siz[x]);
if(big[x]<big[root]) root=x;
}
int cal_black(int x,int fa,int sum)
{
if(sum==k) return k;
int res=sum;
for(int i=front[x];i;i=nxt[i])
{
if(vis[to[i]] || to[i]==fa) continue;
res=max(res,cal_black(to[i],x,sum+crowd[to[i]]));
}
return res;
}
bool cmp(node p,node q)
{
return p.black<q.black;
}
void cal_dis(int x,int fa,int sum,int d)
{
if(sum<=k)
{
ans=max(ans,d);
dis[sum]=max(dis[sum],d);
}
for(int i=front[x];i;i=nxt[i])
{
if(to[i]==fa || vis[to[i]]) continue;
cal_dis(to[i],x,sum+crowd[to[i]],d+val[i]);
}
}
void cal(int x)
{
tot=max_black=;
for(int i=front[x];i;i=nxt[i])
{
if(vis[to[i]]) continue;
e[++tot].id=to[i];
e[tot].black=cal_black(to[i],x,crowd[to[i]]);
e[tot].d=val[i];
max_black=max(max_black,e[tot].black);
}
sort(e+,e+tot+,cmp);
memset(f,-,sizeof(*f)*(max_black+));
for(int i=;i<=tot;i++)
{
memset(dis,-,sizeof(*dis)*(e[i].black+));
cal_dis(e[i].id,x,crowd[e[i].id],e[i].d);
for(int j=crowd[e[i].id];j<=min(k-crowd[x],e[i].black);j++)
ans=max(ans,f[min(k-j-crowd[x],e[i-].black)]+dis[j]);
f[]=max(f[],dis[]);
for(int j=;j<=e[i].black;j++)
f[j]=max(f[j],dis[j]),f[j]=max(f[j-],f[j]);
}
}
void work(int x)
{
cal(x);
vis[x]=true;
for(int i=front[x];i;i=nxt[i])
{
if(vis[to[i]]) continue;
all=siz[to[i]];
root=;
getroot(to[i],);
work(root);
}
}
int main()
{
read(n); read(k); read(m);
int x;
while(m--)
{
read(x);
crowd[x]=true;
}
int u,v,w;
for(int i=;i<n;i++)
{
read(u); read(v); read(w);
add(u,v,w);
}
big[root]=n;
root=;
all=n;
getroot(,);
work(root);
printf("%d",ans);
}
spoj 1825 Free tour II的更多相关文章
- SPOJ 1825 Free tour II (树的点分治)
题目链接 Free tour II 题意:有$N$个顶点的树,节点间有权值, 节点分为黑点和白点. 找一条最长路径使得 路径上黑点数量不超过K个 这是树的点分治比较基本的题,涉及树上启发式合并……仰望 ...
- SPOJ 1825 Free tour II 树分治
题意: 给出一颗边带权的数,树上的点有黑色和白色.求一条长度最大且黑色节点不超过k个的最长路径,输出最长的长度. 分析: 说一下题目的坑点: 定义递归函数的前面要加inline,否则会RE.不知道这是 ...
- 【SPOJ】1825. Free tour II(点分治)
http://www.spoj.com/problems/FTOUR2/ 先前看了一会题解就自己yy出来了...对拍过后交tle.................. 自己造了下大数据........t ...
- SPOJ:Free tour II (树分治+启发式合并)
After the success of 2nd anniversary (take a look at problem FTOUR for more details), this 3rd year, ...
- SPOJ FTOUR2 - Free tour II
Description 有些黑点,问你选择不超过 \(k\) 个黑点的路径,路径权值最大是多少. Sol 点分治. 这是qzc的论文题,不过我感觉他的翻译好强啊...我还是选择了自己去看题目... 点 ...
- [spoj] FTOUR2 FREE TOUR II || 树分治
原题 给出一颗有n个点的树,其中有M个点是拥挤的,请选出一条最多包含k个拥挤的点的路径使得经过的权值和最大. 正常树分治,每次处理路径,更新答案. 计算每棵子树的deep(本题以经过拥挤节点个数作为d ...
- SPOJ 1825 Free Tour | 终极之树分治
求树上最长路径使得经过的拥挤节点个数不超过K //欢迎访问这个博客!http://www.cnblogs.com/luyouqi233/p/8036828.html #include<cstdi ...
- SPOJ1825 FTOUR2 - Free tour II
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- 后缀自动机(SAM):SPOJ Longest Common Substring II
Longest Common Substring II Time Limit: 2000ms Memory Limit: 262144KB A string is finite sequence of ...
随机推荐
- 20181016-4 Alpha阶段第1周/共2周 Scrum立会报告+燃尽图 04
此作业要求https://edu.cnblogs.com/campus/nenu/2018fall/homework/2248 Scrum master:徐常实 一.小组介绍 组长:王一可 组员:范靖 ...
- Python学习之路8 - 内置方法
abs(-230) #取绝对值 all([0,1,-5]) #如果参数里面的所有值都为真就返回真,否则返回假 any([0,1,-5]) #如果参数里面有一个值为真则返回真,否则返回假 ascii([ ...
- Python:集合操作总结
集合是一组无序排列的不重复元素集 [注]:集合的最大作用是对一个序列进行去重操作 一.集合的分类 在Python中集合分为两类,为可变集合(set)和不可变集合(frozenset).对于可变集合(s ...
- vmvare fusion 8
http://jingyan.baidu.com/article/54b6b9c0f8830f2d583b47ce.html 补充:vmware tools 在上面,直接点击安装
- 电梯V2.0
电梯V2.0 GitHub仓库地址 Problem 一栋10层的大楼(楼层编号1-10),设3台无限载重的电梯,初始时电梯停在1层.其中:1号电梯只能停留在奇数层,2号电梯可以各层都停留,3号电梯只停 ...
- 面试Tips
面试Tips 面向对象:准备找工作的同学 内容概述:关于面试的一些经验总结,希望能带给你些许帮助.若有描述不准确的地方,欢迎指点建议. 内容提炼:共分为四阶段 1.面试前之静生慧 (1)课本知识过一遍 ...
- 网页移动到一个高度后加载网页元素【getBoundingClientRect好用】
$(window).scroll(function () { var windowH = $(window).height();//取可视窗口的高度 ).getBoundingClientRect() ...
- Testng 运行Cannot find class in classpath
用Testng运行多个class,结果报: org.testng.TestNGException: Cannot find class in classpath: Salesman at or ...
- [BZOJ4540][HNOI2016]序列 莫队
4540: [Hnoi2016]序列 Time Limit: 20 Sec Memory Limit: 512 MB Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n ...
- 【刷题】BZOJ 1180 [CROATIAN2009]OTOCI
Description 给出n个结点以及每个点初始时对应的权值wi.起始时点与点之间没有连边.有3类操作: 1.bridge A B:询问结点A与结点B是否连通. 如果是则输出"no&quo ...