传送门

题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小。


思路:

考虑点分治如何合并。

我们利用树形dpdpdp求树的直径的方法,边dfsdfsdfs子树边统计答案即可。

代码:

#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
typedef pair<int,int> pii;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
const int N=2e5+5,K=1e6+5,inf=0x3f3f3f3f;
int n,k,siz[N],msiz[N],ans=inf,top=0,rt,all;
bool vis[N];
vector<pii>e[N];
void findroot(int p,int fa){
	siz[p]=1,msiz[p]=0;
	for(ri i=0,v;i<e[p].size();++i){
		if((v=e[p][i].fi)==fa||vis[v])continue;
		findroot(v,p),siz[p]+=siz[v],msiz[p]=max(msiz[p],siz[v]);
	}
	msiz[p]=max(msiz[p],all-siz[p]);
	if(msiz[p]<msiz[rt])rt=p;
}
struct DP{
	int a[K],stk[K],top;
	bool in[K];
	inline int idx(int k){return in[k]?a[k]:inf;}
	inline void insert(int x,int v){
		if(in[x])a[x]=min(a[x],v);
		else stk[++top]=x,in[x]=1,a[x]=v;
	}
	inline pii delet(){return in[stk[top]]=0,--top,pii(stk[top+1],a[stk[top+1]]);}
	inline void clear(){while(top)delet();}
}f,g;
void solve(int p,int fa,int dep,int dist){
	if(dist>k)return;
	g.insert(dist,dep);
	ans=min(ans,min(dep+f.idx(k-dist),(dist==k)?dep:inf));
	for(ri i=0,v;i<e[p].size();++i){
		if((v=e[p][i].fi)==fa||vis[v])continue;
		solve(v,p,dep+1,dist+e[p][i].se);
	}
}
void dfs(int p){
	vis[p]=1;
	for(ri i=0,v;i<e[p].size();++i){
		if(vis[v=e[p][i].fi])continue;
		solve(v,p,1,e[p][i].se);
		while(g.top){
			pii tmp=g.delet();
			f.insert(tmp.fi,tmp.se);
		}
	}
	f.clear();
	for(ri i=0,v;i<e[p].size();++i){
		if(vis[v=e[p][i].fi])continue;
		rt=0,all=siz[v],findroot(v,0),dfs(rt);
	}
}
int main(){
	n=read(),k=read();
	for(ri i=1,u,v,w;i<n;++i)u=read()+1,v=read()+1,w=read(),e[u].push_back(pii(v,w)),e[v].push_back(pii(u,w));
	msiz[rt=0]=all=n,findroot(1,0),dfs(rt);
	if(ans>n)puts("-1");
	else cout<<ans;
	return 0;
}

2019.01.09 bzoj2599: [IOI2011]Race(点分治)的更多相关文章

  1. [bzoj2599][IOI2011]Race——点分治

    Brief Description 给定一棵带权树,你需要找到一个点对,他们之间的距离为k,且路径中间的边的个数最少. Algorithm Analyse 我们考虑点分治. 对于子树,我们递归处理,所 ...

  2. BZOJ2599:[IOI2011]Race(点分治)

    Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 Input 第一行 两个整数 n, k 第二 ...

  3. AWS re:Invent(2019.01.09)

    时间:2019.01.09地点:北京国际饭店

  4. 【BZOJ-2599】Race 点分治

    2599: [IOI2011]Race Time Limit: 70 Sec  Memory Limit: 128 MBSubmit: 2590  Solved: 769[Submit][Status ...

  5. BZOJ 2599: [IOI2011]Race( 点分治 )

    数据范围是N:20w, K100w. 点分治, 我们只需考虑经过当前树根的方案. K最大只有100w, 直接开个数组CNT[x]表示与当前树根距离为x的最少边数, 然后就可以对根的子树依次dfs并更新 ...

  6. [IOI2011]Race 点分治

    [IOI2011]Race LG传送门 点分治板子题. 直接点分治统计,统计的时候开个桶维护下就好了. 注(tiao)意(le)细(hen)节(jiu). #include<cstdio> ...

  7. bzoj2599: [IOI2011]Race(点分治)

    写了四五道点分治的题目了,算是比较理解点分治是什么东西了吧= = 点分治主要用来解决点对之间的问题的,比如距离为不大于K的点有多少对. 这道题要求距离等于K的点对中连接两点的最小边数. 那么其实道理是 ...

  8. [luogu4149][bzoj2599][IOI2011]Race【点分治】

    题目描述 给一棵树,每条边有权.求一条简单路径,权值和等于 K,且边的数量最小. 题解 比较明显需要用到点分治,我们定义\(d\)数组表示当前节点到根节点\(rt\)之间有多少个节点,也可以表示有多少 ...

  9. bzoj2599/luogu4149 [IOI2011]Race (点分治)

    点分治.WA了一万年. 重点就是统计答案的方法 做法一(洛谷AC bzojWA 自测WA): 做点x时记到x距离为k的边数最小值为dis[k],然后对每一对有值的dis[i]和dis[K-i],给an ...

随机推荐

  1. Python+Selenium学习--定位iframe中的对象

    场景 在web 应用中经常会出现frame 嵌套的应用,假设页面上有A.B 两个frame,其中B 在A 内,那么定位B 中的内容则需要先到A,然后再到B.      switch_to_frame ...

  2. Shell教程 之printf命令

    上一章节我们学习了 Shell 的 echo 命令,本章节我们来学习 Shell 的另一个输出命令 printf. printf 命令模仿 C 程序库(library)里的 printf() 程序. ...

  3. 最近读jdk源码一些基础的总结(有待后续深入)

    第一点:java.lang 1.Object类,hashCode()方法,equals()方法,clone()方法,toString()方法,notify()和notifyAll()方法,wait() ...

  4. 100-days: Seven

    Title: Can baiju, China's sorghum firewater, go global? sorghum n. 高粱 firewater n. 烈酒 Baijiu——a broa ...

  5. vue 添加子路由,并对路由重定向

    // 用户信息首页 { path: '/user/index', name: 'userIndex', component: userIndex, redirect: '/user/index/sho ...

  6. ABAP中不修改内表参照的结构,给内表/结构体增加字段

    Situation: DATA:       itab  TYPE STANDARD TABLE OF zsrsodtla_stru1,      wa_itab TYPE zsrsodtla_str ...

  7. go语言使用go-sciter创建桌面应用(五) 加载元素资源

    有些时候我们需要动态的给某个UI元素加载内容或数据. demo6.go代码如下: package main; import ( "github.com/sciter-sdk/go-scite ...

  8. 多线程的异常处理、线程取消、临时变量、lock

    异步多线程的异常,抓不到,因为是在子线程执行. #region 多线程的异常处理.线程取消.临时变量.lock { try { List<Task> list = new List< ...

  9. JAVA软件安装

    Java配置----JDK开发环境搭建及环境变量配置 文章来源:http://www.cnblogs.com/smyhvae/p/3788534.html Tomcat安装.配置和部署笔记 文章来源: ...

  10. 26.mysql日志

    26.mysql日志mysql日志包括:错误日志.二进制日志.查询日志.慢查询日志. 26.1 错误日志错误日志记录了mysqld启动到停止之间发生的任何严重错误的相关信息.mysql故障时应首先查看 ...