[spoj] FTOUR2 FREE TOUR II || 树分治
原题
给出一颗有n个点的树,其中有M个点是拥挤的,请选出一条最多包含k个拥挤的点的路径使得经过的权值和最大。
正常树分治,每次处理路径,更新答案。
计算每棵子树的deep(本题以经过拥挤节点个数作为deep),然后记录mx[i]为当前为止经过i个拥挤节点所达到的最大价值,tmp[i]为当前所在树中经过i个拥挤节点所达到的最大价值,用于更新答案即可。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#define N 200010
using namespace std;
int ans,n,K,m,cnt,head[N],f[N];
vector < pair<int,int> > v;
struct hhh
{
int to,next,w;
}edge[2*N];
int read()
{
int ans=0,fu=1;
char j=getchar();
for (;j<'0' || j>'9';j=getchar()) if (j=='-') fu=-1;
for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
return ans*fu;
}
void add(int u,int v,int w)
{
edge[cnt].to=v;edge[cnt].next=head[u];edge[cnt].w=w;head[u]=cnt++;
edge[cnt].to=u;edge[cnt].next=head[v];edge[cnt].w=w;head[v]=cnt++;
}
void getroot(int x,int fa)
{
sze[x]=1;
son[x]=0;
for (int i=head[x];i;i=edge[i].next)
if (!vis[edge[i].to] && edge[i].to!=fa)
{
getroot(edge[i].to,x);
son[x]=max(son[x],sze[edge[i].to]);
sze[x]+=sze[edge[i].to];
}
son[x]=max(son[x],sum-sze[x]);
if (son[x]<son[rt]) rt=x;
}
void getdis(int x,int fa)
{
deep_mx=max(deep_mx,deep[x]);
for (int i=head[x];i;i=edge[i].next)
if (!vis[edge[i].to] && edfe[i].to!=fa)
{
deep[edge[i].to]=deep[x]+color[edge[i].to];
dis[edge[i].to]=dis[x]+edge[i].w;
getdis(edge[i].to,x);
}
}
void getmx(int x,int fa)
{
tmp[deep[x]]=max(tmp[deep[x]],dis[x]);
for (int i=head[x];i;i=edge[i].to)
if (!vis[edge[i].to] && edge[i].to!=fa)
getmx(edge[i].to,x);
}
void solve(int x)
{
vis[x]=1;
v.clear();
for (int i=head[x];i;i=edge[i].next)
if (!vis[edge[i].to])
{
deep_mx=0;
deep[edge[i].to]=color[edge[i].to];
dis[edge[i].to]=edge[i].ww;
getdis(edge[i].to,x);
v.push_back(make_pair(deep_mx,edge[i].to));
}
sort(v.begin(),v.end());
int s=v.size();
for (int i=0;i<s;i++)
{
getmx(st[i].second,x);
int now=0;
if (i!=0)
for (int j=v[i].first;j>=0;j--)
{
while (now+j<K && now<st[i-1].first)
now++,mx[now]=max(mx[now],mx[now-1]);
if (now+j<=K) ans=max(mx[now]+tmp[j]);
}
if (i!=s-1)
for (int j=0;j<=v[i].first;j++)
mx[j]=max(mx[j],tmp[j]),tmp[j]=0;
else
for (int j=0;j<=v[i].first;j++)
{
if (j<=K) ans=max(ans,max(tmp[j],mx[j]));
tmp[j]=mx[j]=0;
}
}
}
int main()
{
n=read();
K=read();
m=read();
for (int i=1;i<=m;i++)
{
int x=read();
color[x]=1;
}
for (int i=1,u,v,w;i<n;i++)
{
u=read();v=read();w=read();
add(u,v,w);
}
sum=n;
f[0]=n;
getroot(1,0);
solve(rt);
printf("%d",ans);
return 0;
}
[spoj] FTOUR2 FREE TOUR II || 树分治的更多相关文章
- SPOJ 1825 Free tour II 树分治
题意: 给出一颗边带权的数,树上的点有黑色和白色.求一条长度最大且黑色节点不超过k个的最长路径,输出最长的长度. 分析: 说一下题目的坑点: 定义递归函数的前面要加inline,否则会RE.不知道这是 ...
- SPOJ FTOUR2 - Free tour II
Description 有些黑点,问你选择不超过 \(k\) 个黑点的路径,路径权值最大是多少. Sol 点分治. 这是qzc的论文题,不过我感觉他的翻译好强啊...我还是选择了自己去看题目... 点 ...
- SP1825 FTOUR2 - Free tour II 点分治+启发式合并+未调完
题意翻译 给定一棵n个点的树,树上有m个黑点,求出一条路径,使得这条路径经过的黑点数小于等于k,且路径长度最大 Code: #include <bits/stdc++.h> using n ...
- SPOJ 1825 Free tour II (树的点分治)
题目链接 Free tour II 题意:有$N$个顶点的树,节点间有权值, 节点分为黑点和白点. 找一条最长路径使得 路径上黑点数量不超过K个 这是树的点分治比较基本的题,涉及树上启发式合并……仰望 ...
- SPOJ1825 FTOUR2 - Free tour II
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- SPOJ:Free tour II (树分治+启发式合并)
After the success of 2nd anniversary (take a look at problem FTOUR for more details), this 3rd year, ...
- spoj 1825 Free tour II
http://www.spoj.com/problems/FTOUR2/ After the success of 2nd anniversary (take a look at problem FT ...
- FTOUR2 - Free tour II
传送门 题目翻译的很清楚……似乎点分治的题题目描述都非常简洁. 还是那个操作,一条路径要么全部在一棵子树中,要么经过当前的重心,所以考虑点分治. 首先dfs求出重心的每一棵子树中,有i个黑点的最长路径 ...
- SP1825 【FTOUR2 - Free tour II】
# \(SP1825\) 看到没有人用老师的办法,于是自己写一下思路 思路第一步:排除旧方法 首先这道题和\(4178\)不一样,因为那道题是计数,而这道题是求最值,最值有个坏处,就是对于来自相同子树 ...
随机推荐
- BZOJ1053: [HAOI2007]反素数ant(爆搜)
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4163 Solved: 2485[Submit][Status][Discuss] Descript ...
- 10^9以上素数判定,Miller_Rabin算法
#include<iostream> #include<cstdio> #include<ctime> #include<string.h> #incl ...
- Windows下MySQL数据库的安装与关闭开机自启动
我在学习java,安装数据库时找了很多教程,现在在这里总结一下我安装数据库的过程,我安装的是mysql-5.6.42-winx64版本的. 数据官方下载地址:https://dev.mysql.com ...
- js中break跳出多层循环
// 当执行多重循环的时候break的情况 outer: for(var i=0;i<10;i++){ inter: for(var j=0;j<10;j++){ if(i>5){ ...
- Error: Cannot find module 'core-js/fn/array/values' at Function.Module._resolveFilename (module
E:\codeBase\top605\rescue-master\server\node_modules\_log4js@1.1.1@log4js\lib\log4js.js:321 throw ne ...
- 吴恩达DeepLearning 第一课第四周随笔
第四周 4.1深度神经网络符号约定 L=4______(神经网络层数) 4.2 校正矩阵的维数 校正要点:,, dZ,dA,dW,db都与它们被导数(Z,A,W,b)的维数相同 4.3 为什么使用 ...
- poj 2674 线性世界 弹性碰撞
弹性碰撞的题目一般都是指碰到就会掉转方向的一类题目,这里我们可以忽略掉头,仅仅看成擦肩而过,交换名字等等 题意:一条线上N只蚂蚁,每只蚂蚁速度固定,方向和坐标不同,碰头后掉头,求最后掉下去那只蚂蚁的名 ...
- 3,Python常用库之三:Matplotlib
一.Matplotlib基础知识 Matplotlib中的基本图表包括的元素 x轴和y轴 axis水平和垂直的轴线 x轴和y轴刻度 tick刻度标示坐标轴的分隔,包括最小刻度和最大刻度 x轴和y轴刻度 ...
- MyBatis---集合查询(一对多)
这里的集合查询即一对多的数据联合查询.如一个用户多次登录的信息查询 要实现这样的联合查询需要在用户实体类中添加登录实体类的一个集合属性字段,表中不存在该字段. <resultMap id=&qu ...
- node-sass安装不成功的问题
SASS_BINARY_SITE=https://npm.taobao.org/mirrors/node-sass/ npm install node-sass 简单粗暴的执行上述的命令.