题意:

边权可能为负

思路:

感觉我自己写的还是太过僵硬了,可以灵活一点,比如可以多写几个不同的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. 如何在ABAP里用函数式编程思想打印出非波拉契Fibonacci(数列)

    在JavaScript里可以用ES6提供的FunctionGenerator这种黑科技来打印非波拉契数列,具体细节参考我这篇文章. 在ABAP里也有很多种方式实现这个需求. 下面这个report分别用 ...

  2. Linux OpenGL 实践篇-14-多实例渲染

    多实例渲染 OpenGL的多实例渲染是一种连续执行多条相同的渲染命令的方法,并且每条命令产生的结果都有轻微的差异,通常用于渲染大量的几何物体. 设想一个场景,比如太空,我们需要渲染数以万记的星球,如果 ...

  3. 运行spark自带的例子出错及解决

    以往都是用java运行spark的没问题,今天用scala在eclipse上运行spark的代码倒是出现了错误 ,记录 首先是当我把相关的包导入好后,Run,报错: Exception in thre ...

  4. 国家气象局提供的天气预报接口(完整Json接口)

    国家气象局提供的天气预报接口主要有三个,分别是:http://www.weather.com.cn/data/sk/101010100.htmlhttp://www.weather.com.cn/da ...

  5. SniperOj-shorter-shellcode-x86

    shell-storm 这里可以有一些可以用的shellcode,不过自己写才是biner的骄傲 /奋斗 0x00 不会写shellcode(和一条咸鱼有什么区别/哭) 0x01 这题目前有俩种解法 ...

  6. Bootstrap 网格系统(Grid System)实例1

    Bootstrap 网格系统(Grid System)实例:堆叠水平 <!DOCTYPE html><html><head><meta http-equiv= ...

  7. ios retain copy 以及copy协议

    阅读本文之前首先了解Copy与Retain的区别: Copy是创建一个新对象,Retain是创建一个指针,引用对象计数加1. Copy属性表示两个对象内容相同,新的对象retain为1 ,与旧有对象的 ...

  8. CF-1099 D. Sum in the tree

    CF-1099 D. Sum in the tree 题意:结点序号为 1~n 的一个有根树,根序号为1,每个点有一个权值a[i], 然后定义一s[i]表示从根节点到 结点序号为i的结点的路途上所经过 ...

  9. python私有成员与公有成员(_和__)

    python并没有对私有成员提供严格的访问保护机制. 在定义类的成员时,如果成员名以两个下划线“__”或更多下划线开头而不以两个或更多下划线结束则表示是私有成员. 私有成员在类的外部不能直接访问,需要 ...

  10. log4j日志输出到文件的配置

    1.Maven的dependency 2.log4j.properties的配置 3.Junit的Test类 4.web.xml的配置(非必要) 5.spring的db.config的配置(非必要) ...