题目链接

problem

一棵n个点带边权的树,有m个条路径。选择一条边,将其权值变为0,使得长度最长的路径长度最小。求该长度最小为多少。

solution

其实仔细一想并不难。

删除一条边会导致所有经过这条边的路径长度减少该边长度。所有没经过这条边的路径长度不变。

所以我们只需要知道没经过该边的路径中的长度最大值,以及经过该边的路径中长度最大值。

显然经过该边的路径长度最大值我们可以当做最长路径的最大值。

现在只要对于每条边都能够计算出没经过该边的路径长度最大值即可。

我们发现并不需要对于每条边都求出该值。

因为删除的边肯定位于最长路径上。

然后我们就把最长路径扯平。并对上面的边进行编号。

如图,对于\(S-T\)这条路径,会在删除\(1,4,5\)这三条边时产生贡献。所以我们只要用两个数组分别记录出前缀最大值和后缀最大值即可。

然后枚举删除的边,记录最优答案。

code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 300100,logN = 20;
ll read() {
ll x = 0,f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
struct node {
int u,v,nxt,w,bz;
}e[N << 1];
int head[N],ejs;
void add(int u,int v,int w) {
e[++ejs].v = v;e[ejs].u = u;e[ejs].nxt = head[u];head[u] = ejs;e[ejs].w = w;
} int id[N],cnt,dis[N]; int DFS(int u,int V,int fa) {
if(u == V) {
id[u] = ++cnt;return 1;
}
for(int i = head[u];i;i = e[i].nxt) {
int v = e[i].v;
if(v == fa) continue;
if(DFS(v,V,u)) {
id[u] = ++cnt;
e[i].bz = 1;
return 1;
}
}
return 0;
}
void mark(int u,int p) {
id[u] = p;
for(int i = head[u];i;i = e[i].nxt) {
int v = e[i].v;
if(id[v]) continue;
mark(v,p);
}
}
int lca[N][21],dep[N];
void get_lca(int u,int fa) {
dep[u] = dep[fa] + 1; for(int i = 1;i <= logN;++i) lca[u][i] = lca[lca[u][i - 1]][i - 1]; for(int i = head[u];i;i = e[i].nxt) {
int v = e[i].v;
if(v == fa) continue;
dis[v] = dis[u] + e[i].w;
lca[v][0] = u;
get_lca(v,u);
} }
int LCA(int x,int y) {
if(dep[x] < dep[y]) swap(x,y); for(int i = logN;i >= 0;--i)
if(dep[lca[x][i]] >= dep[y]) x = lca[x][i]; for(int i = logN;i >= 0;--i)
if(lca[x][i] != lca[y][i]) x = lca[x][i],y = lca[y][i]; if(x != y) return lca[x][0];
return x; }
int mx1[N],mx2[N];
struct QUE {
int s,t,len;
}Q[N];
int main() {
int mxx = 0;
int n = read(),m = read(); for(int i = 1;i < n;++i) {
int u = read(),v = read(),w = read();
add(u,v,w);add(v,u,w);
} get_lca(1,0); int S = 0,T = 0; for(int i = 1;i <= m;++i) {
Q[i].s = read();Q[i].t = read();
Q[i].len = dis[Q[i].s] + dis[Q[i].t] - dis[LCA(Q[i].s,Q[i].t)] * 2;
if(Q[i].len > mxx) {
mxx = Q[i].len;
S = Q[i].s;T = Q[i].t;
}
} DFS(S,T,0); for(int i = 1;i <= n;++i) {
if(id[i]) {
mark(i,id[i]);
}
} for(int i = 1;i <= m;++i) {
int s = Q[i].s,t = Q[i].t; int l = id[s],r = id[t];
if(l > r) swap(l,r); mx1[l - 1] = max(mx1[l - 1],Q[i].len);
mx2[r] = max(mx2[r],Q[i].len);
} for(int i = cnt;i >= 0;--i) {
mx1[i] = max(mx1[i],mx1[i + 1]);
}
for(int i = 1;i <= cnt;++i)
mx2[i] = max(mx2[i],mx2[i - 1]); int ans = 1e9; for(int i = 1;i <= ejs;++i) {
if(e[i].bz) {
int l = id[e[i].u],r = id[e[i].v];
if(l > r) swap(l,r); int k = max(max(mx1[l],mx2[l]),mxx - e[i].w); ans = min(ans,k);
}
} cout<<(ans == 1e9 ? 0 : ans); return 0;
}

Noip2015Day2T3 运输计划的更多相关文章

  1. Vijos1983 NOIP2015Day2T3 运输计划 transport LCA

    题目链接Vijos 题目链接UOJ 该博客在博客园的链接 转载一个大佬的题解: 点击这里->大佬题解 下面谈谈我的感悟: 当然写代码也是写的很艰辛: 我力劝C++的同胞们,这题卡常数,Dfs党会 ...

  2. NOIP2015Day2T3运输计划(二分+树上差分)

    做了这么多NOIPTG的题,这是唯一 一道一眼秒的T3(有时候T2还不会做QAQ)... 题目大意就不说了QWQ 思路大概是:啊最大值最小化,来个二分.检验mid的话,显然就是用最长路径减去所有边权& ...

  3. 运输计划NOIP2015Day2T3

    运输计划 题目描述 公元 2044 年,人类进入了宇宙纪元. L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条 航道连通了 L 国的所有星球. 小 P 掌管一 ...

  4. bzoj 4326: NOIP2015 运输计划

    4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MB Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个 ...

  5. noip2015 运输计划

    描述 公元 2044 年,人类进入了宇宙纪元.L 国有 nn 个星球,还有 n−1n−1 条双向航道,每条航道建立在两个星球之间,这 n−1n−1 条 航道连通了 L 国的所有星球. 小 P 掌管一家 ...

  6. 【bzoj4326】[NOIP2015]运输计划

    题目描述 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家物流公司, 该 ...

  7. [题解]vijos 运输计划

    Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家 ...

  8. NOIP2015 运输计划(bzoj4326)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 886  Solved: 574[Submit][Status] ...

  9. UOJ #150 【NOIP2015】 运输计划

    题目描述 公元 \(2044\) 年,人类进入了宇宙纪元. \(L\) 国有 \(n\) 个星球,还有 \(n-1\) 条双向航道,每条航道建立在两个星球之间,这 \(n-1\) 条航道连通了 \(L ...

随机推荐

  1. linux用户身份与文件权限

    用户 useradd [ 参数 ] 用户名 添加用户 sudo useradd -d /home/test -u 1001 -s /bin/bash name usermod [选项] 用户名 更改用 ...

  2. 分布式全局唯一ID生成策略​

    一.背景 分布式系统中我们会对一些数据量大的业务进行分拆,如:用户表,订单表.因为数据量巨大一张表无法承接,就会对其进行分库分表. 但一旦涉及到分库分表,就会引申出分布式系统中唯一主键ID的生成问题. ...

  3. This system is not registered with ULN

    [root@DBDATA yum.repos.d]# yum makecacheLoaded plugins: aliases, changelog, downloadonly, fastestmir ...

  4. PWA 学习笔记(一)

    PWA 介绍 概念: PWA(Progressive web apps,渐进式 Web 应用)运用现代 Web API 和传统的渐进式增强策略来创建跨平台 Web 应用程序 它并不是一个快捷方式,而能 ...

  5. s3c2440裸机-内存控制器(五、SDRAM编程实现)

    配置内存控制器-SDRAM编程配置 2440内存控制器共有13个寄存器. BANK0--BANK5只需要设置BWSCON和BANKCONx(x为0-5)两个寄存器: BANK6.BANK7外接SDRA ...

  6. 逻辑卷管理器LVM

    逻辑卷管理器LVM •将设备指定为物理卷 • 用一个或者多个物理卷来创建一个卷组 • 物理卷是用固定大小的物理区域(Physical Extent,PE)来定义的 • 在物理卷上创建的逻辑卷是由物理区 ...

  7. koa2跨域模块koa2-cors

    之前写了一个api在小程序里调用,但是我不想每次都打开小程序,所以想写一个简单的网页,但是遇到CORB的问题: 经尝试,jsonp等都没起作用,由于我后台是koa写的,发现koa2-cors库可以解决 ...

  8. .net core 在 Docker 上的部署

    Docker可以说是现在微服务,DevOps的基础,咱们.Net Core自然也得上Docker..Net Core发布到Docker容器的教程网上也有不少,但是今天还是想来写一写.你搜.Net co ...

  9. 【linux命令】chgrp改变文件或目录的属组

    在lunix系统里,文件或目录的权限的掌控以拥有者及所诉群组来管理.可以使用chgrp指令取变更文件与目录所属群组,这种方式采用群组名称或群组识别码都可以.Chgrp命令就是change group的 ...

  10. NXP恩智浦VEGA织女星开发板免费申请!

    前言 大概两周前申请了一块NXP恩智浦的开发板,今天终于收到了!在这里推荐给大家,官方网站刚上线一个月左右,目前申请的人还不算多,感兴趣的朋友可以申请一个,体验一下这个四核性能怪兽.大厂就是大气,包装 ...