Description

给一棵树,每条边有非负权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, 1 <= K <= 1000000

Input

第一行 两个整数 n, k

第二..n行 每行三个整数 表示一条无向边的两端和权值 (注意点的编号从0开始)

Output

一个整数 表示最小边数量 如果不存在这样的路径 输出-1

Sample Input

4 3

0 1 1

1 2 2

1 3 4

Sample Output

2

题解

做了一上午的狗屎题,其实很水(点分裸题)...老是找不出细节错误....

  • 在每一棵点分治的树中只考虑经过根的路径;

    • (1)某一点到根的路径

      • 只需要算出每个点到根的距离即可判断。
    • (2)来自根节点不同儿子所在子树的两个点构成的路径
      • 每个点相当于有三个参数$belong[i]$,$dis[i]$,$s[i]$,分别表示删除根后属于哪个联通快,到根的路径长度以及路径上的边数;
      • 原问题相当于求$min(s[i]+s[j])$,$belong[i]!=belong[j]$,$dis[i]+dis[j]=k$。
  • 依次处理根的每一棵子树;
  • $f[i]$表示已经处理过的子树中到根距离为$i$的点中$s$值最小为多少;
  • 当处理下一棵子树时,每个点所能匹配的点到根的距离都是固定的,直接拿出对应的$f$值更新答案即可,然后利用这棵子树更新$f$数组;
  • 这样保证了更新答案的两点$belong$值不同,$dis$相加等于$k$,同时直接找出当前最优解。
  • 易发现,所有路径都是在这个方法中考虑过的,显然是可行的。
 //It is made by Awson on 2017.9.20
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <string>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define LL long long
using namespace std;
const int N = ;
const int K = ;
const int INF = ~0u>>; inline int Read() {
int sum = ;
char ch = getchar();
while (ch < '' || ch > '') ch = getchar();
while (ch >= '' && ch <= '') sum = (sum<<) + (sum<<) + ch - , ch = getchar();
return sum;
}
int n, k, u, v, c;
struct tt {
int to, cost, next;
}edge[N*+];
int path[N+], top;
int ans = INF;
int size[N+], mxsize[N+];
bool vis[N+];
int minsize, root;
int f[K+]; inline void add(int u, int v, int c) {
edge[++top].to = v;
edge[top].cost = c;
edge[top].next = path[u];
path[u] = top;
}
void dfs_size(int u, int fa) {
size[u] = ;
mxsize[u] = ;
for (int i = path[u]; i; i = edge[i].next)
if ((!vis[edge[i].to]) && edge[i].to != fa) {
dfs_size(edge[i].to, u);
size[u] += size[edge[i].to];
mxsize[u] = Max(mxsize[u], size[edge[i].to]);
}
}
void dfs_getroot(int r, int u, int fa) {
mxsize[u] = Max(mxsize[u], size[r]-size[u]);
if (mxsize[u] < minsize) minsize = mxsize[u], root = u;
for (int i = path[u]; i; i = edge[i].next)
if ((!vis[edge[i].to]) && edge[i].to != fa)
dfs_getroot(r, edge[i].to, u);
}
void dfs_getans(int u, int fa, int cnt, int val) {
if (val > k) return;
if (val == k) {
ans = Min(ans, cnt);
return;
}
int tmp = k-val;
if (f[tmp]) ans = Min(f[tmp]+cnt, ans);
for (int i = path[u]; i; i = edge[i].next)
if ((!vis[edge[i].to]) && edge[i].to != fa)
dfs_getans(edge[i].to, u, cnt+, val+edge[i].cost);
}
void dfs_update(int u, int fa, int cnt, int val) {
if (val >= k) return;
if (!f[val]) f[val] = cnt;
else f[val] = Min(f[val], cnt);
for (int i = path[u]; i; i = edge[i].next)
if ((!vis[edge[i].to]) && edge[i].to != fa)
dfs_update(edge[i].to, u, cnt+, val+edge[i].cost);
}
void dfs_delete(int u, int fa, int val) {
if (val >= k) return;
f[val] = ;
for (int i = path[u]; i; i = edge[i].next)
if ((!vis[edge[i].to]) && edge[i].to != fa)
dfs_delete(edge[i].to, u, val+edge[i].cost);
}
void solve(int x) {
minsize = INF;
dfs_size(x, );
dfs_getroot(x, x, );
vis[root] = true;
for (int i = path[root]; i; i = edge[i].next)
if (!vis[edge[i].to]) {
dfs_getans(edge[i].to, root, , edge[i].cost);
dfs_update(edge[i].to, root, , edge[i].cost);
}
for (int i = path[root]; i; i = edge[i].next)
if (!vis[edge[i].to])
dfs_delete(edge[i].to, root, edge[i].cost);
for (int i = path[root]; i; i = edge[i].next)
if (!vis[edge[i].to])
solve(edge[i].to);
}
void work() {
for (int i = ; i < n; i++) {
u = Read(); v = Read(); c = Read();
u++, v++;
add(u, v, c);
add(v, u, c);
}
ans = INF;
solve();
printf("%d\n", ans == INF ? - : ans);
}
int main() {
int size = << ; //==========//
char *p = (char*)malloc(size) + size; //手 动 扩 栈//
__asm__("movl %0, %%esp\n" :: "r"(p)); //==========//
n = Read(); k = Read();
work();return ;
}

[IOI 2011]Race的更多相关文章

  1. 洛谷 P4149 [ IOI 2011 ] Race —— 点分治

    题目:https://www.luogu.org/problemnew/show/P4149 仍然是点分治: 不过因为是取 min ,所以不能用容斥,那么子树之间就必须分开算,记录桶时注意这个: 每次 ...

  2. 【BZOJ 2599】【IOI 2011】Race 点分治

    裸的点分治,然而我因为循环赋值$s$时把$i <= k$写成$i <= n$了,WA了好长时间 #include<cstdio> #include<cstring> ...

  3. 【IOI 2011】Race

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2599 [算法] 点分治 [代码] #include<bits/stdc++.h ...

  4. [IOI 2011]ricehub

    Description 乡间有一条笔直而长的路称为“米道”.沿着这条米道上 R 块稻田,每块稻田的坐标均为一个 1 到 L 之间(含 1 和 L)的整数.这些稻田按照坐标以不减的顺序给出,即对于 0 ...

  5. 【题解】Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths Codeforces 741D DSU on Tree

    Prelude 很好的模板题. 传送到Codeforces:(* ̄3 ̄)╭ Solution 首先要会DSU on Tree,不会的看这里:(❤ ω ❤). 众所周知DSU on Tree是可以用来处 ...

  6. 【BZOJ-2599】Race 点分治

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

  7. hdu 4123 Bob’s Race 树的直径+rmq+尺取

    Bob’s Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Probl ...

  8. USACO Section 4.3 Street Race(图的连通性+枚举)

    虽说是IOI'95,但是也是挺水的..for 第一问,n最大为50,所以可以直接枚举起点和终点之外的所有点,然后dfs判断是否连通:for 第二问,易知答案一定是第一问的子集,所以从第一问中的答案中枚 ...

  9. POJ 4003 Bob’s Race && HDU4123 Bob’s Race (dfs+rmq)

    Bob’s Race Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 378   Accepted: 119 Descript ...

随机推荐

  1. JavaScript(第一天)【<script>标签浅析】

    一.创建一张HTML页面 初学者创建一张html页面建议借助工具,例如Dreamweaver可视化编辑器.   二.<Script>标签解析 <script>xxx</s ...

  2. 2017-2018-1 Java演绎法 第六七周 作业

    团队任务:修改完善<需求规格说明书>等 团队组长:袁逸灏 本次编辑:刘伟康 修改完善上周提交的需求规格说明书 [markdown 链接] [pdf 链接] 不足之处:仅就现在的问题来看,结 ...

  3. 20155215 第二周测试1 与 myod

    课堂测试 第一题 每个.c一个文件,每个 .h一个文件,文件名中最好有自己的学号 用Vi输入图中代码,并用gcc编译通过 在Vi中使用K查找printf的帮助文档 提交vi编辑过程截图,要全屏,包含自 ...

  4. C语言最后一次博客作业

    1.当初你是如何做出选择计算机专业的决定的? 一开始选专业的时候,说实话我很纠结也很迷茫,对我来说,中学时代,似乎就只要考好试,做好题就可以了,对于未来想要做啥并没有那么多的规划和想法,偶尔跟基友畅聊 ...

  5. map的infowindow的show事件(ArcGIS API for JS)

  6. nyoj 背包问题

    背包问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 现在有很多物品(它们是可以分割的),我们知道它们每个物品的单位重量的价值v和重量w(1<=v,w< ...

  7. 记录Yii2代码调试中出现的两个问题(截图展示)

    1.代码会中断执行,不提示错误信息,是由于substr函数第一个参数为数组造成的 2. 谷歌浏览器调试异步调用接口时出现的错误,需在接口返回处进行断点调试 这两个错误比较隐蔽,调试代码时必须认真仔细

  8. MySQL一些中重要命令

    前言: 最近在面试的过程中,深感对MySQL一些重要命令的缺失.借着这个机会,补补这块的知识.不让自己只会增删查改,懂一些高级的东西 limit 用法 order by 用法 in 和 between ...

  9. 使用pie.htc时Border-radius的兼容

    如果一个图层中(navin)使用了pie.htc来对ie6,7,8进行兼容,如若上一层(navwrap)的样式中有背景的属性,则此层 (navin) 在ie6,7,8中背景颜色不显示.如下图:此部分的 ...

  10. 开发一个http代理服务器

    参考链接: http://www.cnblogs.com/jivi/archive/2013/03/10/2952860.html https://www.2cto.com/kf/201405/297 ...