题目链接

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. Docker Compose部署Nexus3时的docker-compose,yml代码

    场景 Docker-Compose简介与Ubuntu Server 上安装Compose: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...

  2. 头条小视频和西瓜视频signature签名算法

    点击上方↑↑↑蓝字[协议分析与还原]关注我们 "分析今日头条内小视频和西瓜视频分享后浏览器打开所用的signature签名算法." 上月写的一篇关于使用微信的wxid加好友的文章, ...

  3. SpringCloud之Eureka:集群搭建

    上篇文章<SpringCloud之Eureka:服务发布与调用例子>实现了一个简单例子,这次对其进行改造,运行两个服务器实例.两个服务提供者实例,服务调用者请求服务,使其可以进行集群部署. ...

  4. Angular框架入门

    今天简单学习了AngularJS框架,在这里我想简单的总结一下我所了解的AngularJS和一些入门案例! 首先,我们要知道什么是AngularJS? AngularJS  诞生于2009年,由Mis ...

  5. C#&.Net干货分享- 构造SMSWebChineseApi对接第三方短信平台

    你们想要的短信对接,要舍得点钱哦.... /// <summary>    /// http://sms.webchinese.cn/api.shtml    /// </summa ...

  6. linux bash基础特性

    使用history命令,取得命令历史,当bash进程结束后,会把命令历史存放到文件中,下次开机还能看到命令历史. 定制history:通过设置环境变量,来定制history 环境变量$HISTSIZE ...

  7. java中使用lambda表达式

    使用lambda表达式能够使复杂的编写方式变的简单 lambda表达式的语法 (parameters) -> expression 或 (parameters) ->{ statement ...

  8. 《Web Development with Go》JWT认证满意版

    这个比昨晚的要满意, 认证放到中间件那里了. Mux使用的是gorilla, 中间件使用的是negroni, 启动是用的negroni.classic方法. package main import ( ...

  9. JavaScript-----14.内置对象 Array()和String()

    5. 数组对象 5.1数组的创建 之前提到过数组的创建方式 字面量 new Array() //创建数组的两种方式 //1.利用数组字面量 var arr = [1, 2, 3]; console.l ...

  10. Googleplaystore数据分析

    本次所用到的数据分析工具:numpy.pandas.matplotlib.seaborn 一.分析目的 假如接下来需要开发一款APP,想了解开发什么类型的APP会更受欢迎,此次分析可以对下一步计划进行 ...