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 ...
随机推荐
- 简评搜狗输入法(ios端)
首先说说为什么不使用iPhone自带的输入法呢,首先是词库不够丰富,好多简单的词语需要逐个字逐个字的选择,记忆功能不太好,其次是全键盘式的输入我不太习惯,还是九宫格的输入法比较简单,更方便快捷. 搜狗 ...
- FivePlus——成果展示
思路描述:描述对于自己此次任务是如何思考的 这次作业没能帮上什么忙,刚开始还对这次作业有所期待,然而,第一次听他们讨论的时候就??? 之后又去查了一些诸如贪吃蛇类的小游戏,知道大概可以达成什么效果,但 ...
- Java & hashCode作用
首先,想要明白hashCode的作用,你必须要先知道Java中的集合. 总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set.你知道它们的区别吗?前者集合内的元素 ...
- scala程序运行的几种方式
HelloWorld简单实例 object HelloWorld{ def main(args:Array[String]){ println("HelloWorld") } } ...
- QXmlStreamReader/QXmlStreamWriter实现Qt下xml文件读写
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QXmlStreamReader/QXmlStreamWriter实现Qt下xml文件读写 ...
- java 数据结构与算法 之查找法
一.二分查找法 二分查找就是将查找的键和子数组的中间键作比较,如果被查找的键小于中间键,就在左子数组继续查找:如果大于中间键,就在右子数组中查找,否则中间键就是要找的元素. @Test public ...
- Delphi下使用指针的简单总结
由于最近公司太忙,好久没有更新我的BLOG了.原来想着写写关于HOOK驱动的文章,可是最后想想好久已经没有做驱动的东西了,怕写出来有错误,于是作罢.开发游戏也有一段时间了,发现使用DELPHI来开发网 ...
- 中国省市 Json 二级联动
Json数据: var cities = {'北京': ['北京'], '广东': ['广州', '深圳', '珠海', '汕头', '韶关', '佛山', '江门', '湛江', '茂名', '肇庆 ...
- bzoj1211-树的计数
题意 给出 \(n\) 和长度为 \(n\) 的数列 \(d\) 表示每个点的度数,问有多少颗满足要求的树. 分析 这题是prufer编码的应用. prufer编码是对一个带标号无根树的刻画,生成方式 ...
- 【bzoj4011】[HNOI2015]落忆枫音 容斥原理+拓扑排序+dp
题目描述 给你一张 $n$ 个点 $m$ 条边的DAG,$1$ 号节点没有入边.再向这个DAG中加入边 $x\to y$ ,求形成的新图中以 $1$ 为根的外向树形图数目模 $10^9+7$ . 输入 ...