bzoj2599: [IOI2011]Race
来源:互联网 发布:瘦腿 知乎 编辑:程序博客网 时间:2024/06/06 07:50
Description
给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000Input
第一行 两个整数 n, k
第二..n行 每行三个整数 表示一条无向边的两端和权值 (注意点的编号从0开始)Output
一个整数 表示最小边数量 如果不存在这样的路径 输出-1Sample Input
4 3
0 1 1
1 2 2
1 3 4Sample Output
2
颓废了一波的我重新开始更blog了..
这道题比较显然的就是用点分治啊.. 找重心然后再找经过它的所有路径咯..
时间复杂度就是
#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>using namespace std;const int Maxn = 200010;const int Maxk = 1000010;const int inf = 0x7fffffff;struct node { int x, y, next, d;}a[Maxn*2]; int first[Maxn], len;void ins ( int x, int y, int d ){ len ++; a[len].x = x; a[len].y = y; a[len].d = d; a[len].next = first[x]; first[x] = len;}int _min ( int x, int y ){ return x < y ? x : y; }int n, K, cur, s[Maxn], d[Maxn], f[Maxn], core;int alls, ans;int v[Maxk], cnt[Maxk];bool done[Maxn]; int dep[Maxn];void dfs ( int x, int fa ){ s[x] = 1; f[x] = 0; for ( int k = first[x]; k; k = a[k].next ){ int y = a[k].y; if ( y == fa || done[y] == true ) continue; dfs ( y, x ); s[x] += s[y]; if ( s[y] > f[x] ) f[x] = s[y]; } if ( alls-s[x] > f[x] ) f[x] = alls-s[x]; if ( f[core] > f[x] ) core = x;}void calc ( int x, int fa ){ if ( d[x] > K ) return; if ( v[K-d[x]] == cur ) ans = _min ( ans, cnt[K-d[x]]+dep[x] ); for ( int k = first[x]; k; k = a[k].next ){ int y = a[k].y; if ( y == fa || done[y] == true ) continue; d[y] = d[x]+a[k].d; dep[y] = dep[x]+1; calc ( y, x ); }}void update ( int x, int fa ){ if ( d[x] > K ) return; if ( v[d[x]] != cur ){ v[d[x]] = cur; cnt[d[x]] = dep[x]; } else cnt[d[x]] = _min ( cnt[d[x]], dep[x] ); for ( int k = first[x]; k; k = a[k].next ){ int y = a[k].y; if ( y == fa || done[y] == true ) continue; update ( y, x ); }}void solve ( int x ){ done[x] = true; cur = x; v[0] = cur; cnt[0] = 0; for ( int k = first[x]; k; k = a[k].next ){ int y = a[k].y; if ( done[y] == true ) continue; d[y] = a[k].d; dep[y] = 1; calc ( y, x ); update ( y, x ); } for ( int k = first[x]; k; k = a[k].next ){ int y = a[k].y; if ( done[y] == true ) continue; core = 0; alls = f[0] = s[y]; dfs ( y, 0 ); solve (core); }}int main (){ int i, j, k; scanf ( "%d%d", &n, &K ); for ( i = 1; i < n; i ++ ){ int x, y, dd; scanf ( "%d%d%d", &x, &y, &dd ); x ++; y ++; ins ( x, y, dd ); ins ( y, x, dd ); } ans = inf; core = 0; alls = f[0] = n; dfs ( 1, 0 ); memset ( done, false, sizeof (done) ); solve (core); if ( ans == inf ) printf ( "-1\n" ); else printf ( "%d\n", ans ); return 0;}
0 0
- 【bzoj2599】: [IOI2011]Race
- BZOJ2599: [IOI2011]Race
- bzoj2599【IOI2011】Race
- bzoj2599: [IOI2011]Race
- bzoj2599: [IOI2011]Race
- BZOJ2599: [IOI2011]Race
- 【IOI2011】bzoj2599 Race
- bzoj2599: [IOI2011]Race
- 【bzoj2599】[IOI2011]Race
- bzoj2599&COGS2648 [IOI2011]Race
- bzoj2599 [IOI2011]Race
- 【BZOJ2599】[IOI2011]Race
- 【bzoj2599】[IOI2011]Race 点分治
- 【BZOJ2599】[IOI2011]Race【点分治】
- BZOJ2599——[IOI2011]Race
- [BZOJ2599][IOI2011]Race 树分治
- BZOJ2599: [IOI2011]Race 点分治
- bzoj2599: [IOI2011]Race 点分治
- AlexNet学习笔记1-ImageNet Classification with Deep Convolutional Neural Networks
- 使用Oauth构建webapp应用
- JSP中文乱码问题终极解决方案
- java_day1
- 【嵌入式学习笔记】2016年8月6日
- bzoj2599: [IOI2011]Race
- java设计模式_中介者模式
- 为什么正则化(Regularization)可以减少过拟合风险
- SOA治理
- 浅谈端子材质
- linux系统 vi 编辑器实用命令
- java多线程分析
- struts2笔记最终版
- try-catch-finally