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. RTMP消息详细介绍

    本文继上篇简单分析了RTMP协议如何进行通信进一步详细分析RTMP的消息都有哪些,以及这些消息有什么作用. 一.RMTP消息 由上一篇文章可知RTMP 消息有分成两个部分,一个是头部,一个是有效负载. ...

  2. [福大软工教学] W班 第1次成绩排行榜

    作业地址 https://edu.cnblogs.com/campus/fzu/FZUSoftwareEngineering1715W/homework/837 作业要求 (1)回想一下你初入大学时对 ...

  3. Alpha阶段报告-hywteam

    一.Alpha版本测试报告 1. 在测试过程中总共发现了多少Bug?每个类别的Bug分别为多少个? BUG名 修复的BUG 不能重现的BUG 非BUG 没能力修复的BUG 下个版本修复 文件路径的表示 ...

  4. Git使用方法2.0

    ## Git来源: 最早开始是由Ruby程序员们发起的.Ruby是日本的家伙搞出来的,日本有个代码托管网站叫heroku,当时用这个的人比较多,现在这个网站还能打开,网址是www.heroku.com ...

  5. HTTP协议形象展现

    关于http协议:我们分成几个模块说: http协议: HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统. HTTP协议的主要特点可概括如下: 1.支持客户 ...

  6. 在django模板中添加jquery

    路径 /project_name /app_name /templates /index.html /project_name setting.py /static /js jquery.js 导入方 ...

  7. Angular组件——组件生命周期(一)

    组件声明周期以及angular的变化发现机制 红色方法只执行一次. 变更检测执行的绿色方法和和组件初始化阶段执行的绿色方法是一个方法. 总共9个方法. 每个钩子都是@angular/core库里定义的 ...

  8. Faster R-CNN 的 RPN 是啥子?

     Faster R-CNN,由两个模块组成: 第一个模块是深度全卷积网络 RPN,用于 region proposal; 第二个模块是Fast R-CNN检测器,它使用了RPN产生的region p ...

  9. Aache的虚拟主机配置虚拟目录

    3. 打开 httpd.conf 文件, 添加如下代码: # Virtual hosts Include conf/extra/httpd-vhosts.conf 如果已存在,将Include前面的# ...

  10. Spring Cache扩展:注解失效时间+主动刷新缓存(二)

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...