题意:

边权可能为负

思路:

感觉我自己写的还是太过僵硬了,可以灵活一点,比如可以多写几个不同的dfs求出不同的信息,而不是压到同一个dfs里

 #include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
#define fi first
#define se second s
#define MP make_pair
#define N 410000
#define M 1100000
#define MOD 1000000007
#define eps 1e-8
#define pi acos(-1)
#define oo 2e9+1 struct node
{
int x,id;
}b[N]; int head[N],vet[N],nxt[N],len[N],dis[N],dep[N],mxdep[N],son[N],flag[N],c[N],a[N],f[N],tmp[N],mx[N],
n,K,tot,top,ans,sum,root; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} bool cmp(node a,node b)
{
return a.x<b.x||
(a.x==b.x&&a.id<b.id); } void add(int a,int b,int c)
{
nxt[++tot]=head[a];
vet[tot]=b;
len[tot]=c;
head[a]=tot;
} void getroot(int u,int fa)
{
son[u]=; c[u]=;
int e=head[u];
while(e)
{
int v=vet[e];
if(v!=fa&&!flag[v])
{
getroot(v,u);
son[u]+=son[v];
c[u]=max(c[u],son[v]);
}
e=nxt[e];
}
c[u]=max(c[u],sum-c[u]);
if(c[u]<c[root]) root=u;
} void dfs(int u,int fa)
{
mxdep[u]=dep[u];
int e=head[u];
while(e)
{
int v=vet[e];
if(v!=fa&&!flag[v])
{
dep[v]=dep[u]+a[v];
dis[v]=dis[u]+len[e];
dfs(v,u);
mxdep[u]=max(mxdep[u],mxdep[v]);
}
e=nxt[e];
}
} void getmx(int u,int fa)
{
tmp[dep[u]]=max(tmp[dep[u]],dis[u]);
int e=head[u];
while(e)
{
int v=vet[e];
if(v!=fa&&!flag[v]) getmx(v,u);
e=nxt[e];
}
} void work(int u)
{
flag[u]=;
f[]=;
if(a[u]) K--;
int m=;
int e=head[u];
while(e)
{
int v=vet[e];
if(!flag[v])
{
top=;
dep[v]=a[v];
dis[v]=len[e];
dfs(v,u);
b[++m].x=mxdep[v];
b[m].id=v;
}
e=nxt[e];
} sort(b+,b+m+,cmp);
for(int i=;i<=m;i++)
{
int v=b[i].id;
getmx(v,u);
int now=;
if(i>)
{
for(int j=b[i].x;j>=;j--)
{
while(now+j<K&&now<b[i-].x)
{
now++;
mx[now]=max(mx[now],mx[now-]);
}
if(now+j<=K) ans=max(ans,mx[now]+tmp[j]);
}
}
if(i<m)
{
for(int j=;j<=b[i].x;j++)
{
mx[j]=max(mx[j],tmp[j]);
tmp[j]=;
}
}
else
{
for(int j=;j<=b[i].x;j++)
{
if(j<=K) ans=max(ans,max(tmp[j],mx[j]));
tmp[j]=mx[j]=;
}
}
} if(a[u]) K++;
e=head[u];
while(e)
{
int v=vet[e];
if(!flag[v])
{
sum=son[v]; root=;
getroot(v,u);
work(root);
}
e=nxt[e];
} } int main()
{
freopen("spoj1825.in","r",stdin);
freopen("spoj1825.out","w",stdout);
int m;
scanf("%d%d%d",&n,&K,&m);
for(int i=;i<=m;i++)
{
int x;
scanf("%d",&x);
a[x]=;
}
for(int i=;i<=n-;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
ans=;
root=; sum=n; c[]=n; getroot(,);
work(root);
printf("%d\n",ans);
return ;
}

【SPOJ1825】Free tour II (点分治,启发式)的更多相关文章

  1. SP1825 FTOUR2 - Free tour II 点分治+启发式合并+未调完

    题意翻译 给定一棵n个点的树,树上有m个黑点,求出一条路径,使得这条路径经过的黑点数小于等于k,且路径长度最大 Code: #include <bits/stdc++.h> using n ...

  2. spoj1825 Free tour II

    题目链接 一道神奇的点分治 貌似有很多做法,我觉得BIT要好些一些(雾 要求经过黑点数<k就用BIT区间查询前缀 对于每个点用  BIT[0,k-经过黑点数]的最大值+路径长度 使用点分治做到O ...

  3. [spoj] FTOUR2 FREE TOUR II || 树分治

    原题 给出一颗有n个点的树,其中有M个点是拥挤的,请选出一条最多包含k个拥挤的点的路径使得经过的权值和最大. 正常树分治,每次处理路径,更新答案. 计算每棵子树的deep(本题以经过拥挤节点个数作为d ...

  4. SPOJ 1825 Free tour II 树分治

    题意: 给出一颗边带权的数,树上的点有黑色和白色.求一条长度最大且黑色节点不超过k个的最长路径,输出最长的长度. 分析: 说一下题目的坑点: 定义递归函数的前面要加inline,否则会RE.不知道这是 ...

  5. SPOJ 1825 Free tour II (树的点分治)

    题目链接 Free tour II 题意:有$N$个顶点的树,节点间有权值, 节点分为黑点和白点. 找一条最长路径使得 路径上黑点数量不超过K个 这是树的点分治比较基本的题,涉及树上启发式合并……仰望 ...

  6. spoj 1825 Free tour II

    http://www.spoj.com/problems/FTOUR2/ After the success of 2nd anniversary (take a look at problem FT ...

  7. SPOJ:Free tour II (树分治+启发式合并)

    After the success of 2nd anniversary (take a look at problem FTOUR for more details), this 3rd year, ...

  8. SPOJ1825 FTOUR2 - Free tour II

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  9. 【SPOJ】1825. Free tour II(点分治)

    http://www.spoj.com/problems/FTOUR2/ 先前看了一会题解就自己yy出来了...对拍过后交tle.................. 自己造了下大数据........t ...

随机推荐

  1. 成魔笔记1——先入IT,再成魔

    关于我为什么要写这个博客的原因,做一个简单的解释.因为报考的一时兴起,我选择了软件专业.可是三年下来,感觉自己没做多少事,也没收获到多少东西.很多时候都是老师讲什么,都是完全陌生的东西,跟不上教学的思 ...

  2. Linux OpenGL 实践篇-13-geometryshader

    几何着色器 几何着色器是位于图元装配和片元着色器之前的一个着色器阶段,是一个可选阶段.它的输入是一个图元的完整的顶点信息,通常来自于顶点着色器,但如果细分计算着色器启用的话,那输入则是细分计算着色器的 ...

  3. 几个不错的APP网站。

    http://www.yunshipei.com/yunshipei.html http://www.appcan.cn/

  4. 还有这种书,程序开发心理学(豆瓣) - 豆瓣读书,转载自:https://book.douban.com/subject/1141154/

    登录/注册 下载豆瓣客户端 豆瓣 读书 电影 音乐 同城 小组 阅读 FM 时间 豆品 更多 豆瓣读书   购书单 电子图书 豆瓣书店 2018年度榜单 2018书影音报告 购物车 程序开发心理学 作 ...

  5. Jarvis OJ-level3

    使用ret2libc攻击方法绕过数据执行保护 from pwn import* conn = remote("pwn2.jarvisoj.com",9879) elf = ELF( ...

  6. ios之UILabel

    详细使用: UILabel *label = [[UILabelalloc] initWithFrame:CGRectMake(0, 0, 75, 40)];   //声明UIlbel并指定其位置和长 ...

  7. ios之UITabelViewCell的自定义(xib实现2)

    上篇文章介绍了如何用UITableView显示表格,并讲了几种UITableViewCell的风格.不过有时候我们需要自己定义 UITableViewCell的风格,其实就是向行中添加子视图.添加子视 ...

  8. Ecshop的积分商城-对不起,该商品库存不足,现在不能兑换

    1. 打开Ecshop积分商城文件 "根目录/exchange.php" 发现248行与289行都有库存不足时报错的提示代码: 248行:     /* 查询:检查兑换商品是否有库 ...

  9. 【DB_MySQL】查询语句中各子句的执行顺序

    1. FROM 指明查询来源 2. WHERE筛选元组 3. GROUP BY进行分组 4. HAVING 筛选分组 5. SELECT 投影出指定的字段列 6. ORDER BY 对结果集排序 7. ...

  10. tkinter学习-菜单与画布

    阅读目录 Menu 菜单控件 Menubutton 菜单按钮控件 OptionMenu 选项菜单 Canvas 画布控件 Menu: 说明:菜单控件,显示菜单栏,下拉菜单和弹出菜单 属性:创建一个顶级 ...