【SPOJ1825】Free tour II (点分治,启发式)
题意:
边权可能为负
思路:
感觉我自己写的还是太过僵硬了,可以灵活一点,比如可以多写几个不同的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 (点分治,启发式)的更多相关文章
- SP1825 FTOUR2 - Free tour II 点分治+启发式合并+未调完
题意翻译 给定一棵n个点的树,树上有m个黑点,求出一条路径,使得这条路径经过的黑点数小于等于k,且路径长度最大 Code: #include <bits/stdc++.h> using n ...
- spoj1825 Free tour II
题目链接 一道神奇的点分治 貌似有很多做法,我觉得BIT要好些一些(雾 要求经过黑点数<k就用BIT区间查询前缀 对于每个点用 BIT[0,k-经过黑点数]的最大值+路径长度 使用点分治做到O ...
- [spoj] FTOUR2 FREE TOUR II || 树分治
原题 给出一颗有n个点的树,其中有M个点是拥挤的,请选出一条最多包含k个拥挤的点的路径使得经过的权值和最大. 正常树分治,每次处理路径,更新答案. 计算每棵子树的deep(本题以经过拥挤节点个数作为d ...
- SPOJ 1825 Free tour II 树分治
题意: 给出一颗边带权的数,树上的点有黑色和白色.求一条长度最大且黑色节点不超过k个的最长路径,输出最长的长度. 分析: 说一下题目的坑点: 定义递归函数的前面要加inline,否则会RE.不知道这是 ...
- SPOJ 1825 Free tour II (树的点分治)
题目链接 Free tour II 题意:有$N$个顶点的树,节点间有权值, 节点分为黑点和白点. 找一条最长路径使得 路径上黑点数量不超过K个 这是树的点分治比较基本的题,涉及树上启发式合并……仰望 ...
- spoj 1825 Free tour II
http://www.spoj.com/problems/FTOUR2/ After the success of 2nd anniversary (take a look at problem FT ...
- SPOJ:Free tour II (树分治+启发式合并)
After the success of 2nd anniversary (take a look at problem FTOUR for more details), this 3rd year, ...
- SPOJ1825 FTOUR2 - Free tour II
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- 【SPOJ】1825. Free tour II(点分治)
http://www.spoj.com/problems/FTOUR2/ 先前看了一会题解就自己yy出来了...对拍过后交tle.................. 自己造了下大数据........t ...
随机推荐
- 6.3 lambda 表达式
6.3.1 lambda 表达式是一个可传递的代码块,可以在以后执行一次或者多次. 思考(如何按指定时间间隔完成工作,将这个工作放在一个ActionListener的actionPerformed方法 ...
- Xcode - 'openssl/opensslconf.h' file not found解决
点击Build Settings搜索Header Search Paths,添加$(SRCROOT)/目录/Alipay
- 用dfs求联通块(UVa572)
一.题目 输入一个m行n列的字符矩阵,统计字符“@”组成多少个八连块.如果两个字符所在的格子相邻(横.竖.或者对角线方向),就说它们属于同一个八连块. 二.解题思路 和前面的二叉树遍历类似,图也有DF ...
- Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/dispatcher-servlet.xml]
这是因为我把 [/WEB-INF/dispatcher-servlet.xml]的位置换成了[config/springmvc/dispatcher-servlet.xml] 因此idea在原来的位置 ...
- perl 引用(数组和hash引用) --- perlreftut - Mark 的一个简单的'引用'教程 ---Understand References Today. --Mark Jason Dominus, Plover Systems (mjd-perl-ref+@plover.com)
https://blog.csdn.net/fangwei1235/article/details/8570886 首页 博客 学院 下载 论坛 APP 问答 商城 活动 VIP会员 招聘 ITeye ...
- PAT (Basic Level) Practise (中文)-1027. 打印沙漏(20)
PAT (Basic Level) Practise (中文)-1027. 打印沙漏(20) http://www.patest.cn/contests/pat-b-practise/1027 本题 ...
- 八 个优秀的 jQuery Mobile 教程
jQuery Mobile 是 jQuery 在手机上和平板设备上的版本.jQuery Mobile不仅会给主流移动平台带来jQuery核心库,而且会发布一个完整统一的jQuery移动UI框架.虽然j ...
- rhel7.3smb安装配置
rhel7.3smb安装配置 1.安装 yum -y install samba samba-client cifs-utils 2.配置开机自启动,覆盖原配置文件 systemctl enable ...
- Spring根据XML配置文件注入属性 其实也是造bean,看看是使用constructor还是setter顺带完成属性赋值
方法一使用setter方法 package com.swift; public class Book { private String bookName; public void setBook(St ...
- 组件开发中的Controller View模式
“Controller View”模式: 组件嵌套中,最顶层的组件只管理State 子组件为纯组件 顶层组件分配State给子组件,作为子组件的props 子组件接受顶层组件发来的State作为自身的 ...