Description
公元 年,人类进入了宇宙纪元。 L 国有 n 个星球,还有 n− 条双向航道,每条航道建立在两个星球之间,这 n− 条航道连通了 L 国的所有星球。 小 P 掌管一家物流公司, 该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从 ui 号星球沿最快的宇航路径飞行到 vi 号星球去。显然,飞船驶过一条航道是需要时间的,对于航道 j,任意飞船驶过它所花费的时间为 tj,并且任意两艘飞船之间不会产生任何干扰。 为了鼓励科技创新, L 国国王同意小 P 的物流公司参与 L 国的航道建设,即允许小P 把某一条航道改造成虫洞,飞船驶过虫洞不消耗时间。
在虫洞的建设完成前小 P 的物流公司就预接了 m 个运输计划。在虫洞建设完成后,这 m 个运输计划会同时开始,所有飞船一起出发。当这 m 个运输计划都完成时,小 P 的物流公司的阶段性工作就完成了。

如果小 P 可以自由选择将哪一条航道改造成虫洞, 试求出小 P 的物流公司完成阶段性工作所需要的最短时间是多少?
Input Format
第一行包括两个正整数 n,m,表示 L 国中星球的数量及小 P 公司预接的运输计划的数量,星球从 到 n 编号。 接下来 n− 行描述航道的建设情况,其中第 i 行包含三个整数 ai,bi 和 ti,表示第 i 条双向航道修建在 ai 与 bi 两个星球之间,任意飞船驶过它所花费的时间为 ti。数据保证 ≤ai,bi≤n 且 ≤ti≤。 接下来 m 行描述运输计划的情况,其中第 j 行包含两个正整数 uj 和 vj,表示第 j 个运输计划是从 uj 号星球飞往 vj号星球。数据保证 ≤ui,vi≤n
Output Format
输出文件只包含一个整数,表示小 P 的物流公司完成阶段性工作所需要的最短时间。
Sample Input
Sample Output

题目概括:
给一棵带有边权的树,有m条路径,可以使一条边的权值为0,求最远路径的最小值。
题解:
因为题目的数据点给的很明确 因此可以打n*n的去骗前五十分。另外m=1时可以特判另外打个程序骗60分。
60分程序:
#include<cstdio>
#include<algorithm>
int dep[],fa[],last[],next[],e[],val[],cost[],tot,a,b,vv,u[],v[],n,m,ans[];
int ma[][];
void dfs(int x)
{
dep[x]=dep[fa[x]]+;
for (int i=last[x];i;i=next[i])
{
int vv=e[i];
if (vv==fa[x])continue;
cost[vv]=val[i];
fa[vv]=x;
dfs(vv);
}
}
void add(int x,int y,int z){next[++tot]=last[x];last[x]=tot;e[tot]=y;val[tot]=z;}
int jisuan(int i,int x,int y)
{
int tot=;
if (dep[x]<dep[y])std::swap(x,y);
while (dep[x]>dep[y])
{
tot+=cost[x];
ma[x][i]=;
x=fa[x];
}
while (x!=y)
{
tot+=cost[x]+cost[y];
ma[x][i]=;ma[y][i]=;
x=fa[x];y=fa[y];
}
return tot;
}
void work1()//m=1时的情况
{
int Maxx=;long long tot=;
if (dep[u[]]<dep[v[]])std::swap(u[],v[]);
while (dep[u[]]>dep[v[]])
{
tot+=cost[u[]];
Maxx=std::max(Maxx,cost[u[]]);
u[]=fa[u[]];
}
while (u[]!=v[])
{
tot+=cost[u[]]+cost[v[]];
Maxx=std::max(Maxx,cost[u[]]);
Maxx=std::max(Maxx,cost[v[]]);
u[]=fa[u[]];v[]=fa[v[]];
}
printf("%lld",tot-Maxx);
}
void work2()//n*n
{
int Minn=-;
for (int i=;i<=m;i++)ans[i]=jisuan(i,u[i],v[i]),Minn=std::max(Minn,ans[i]);
for (int i=;i<=n;i++)
{
int Maxx=;
for (int j=;j<=m;j++)
Maxx=std::max(Maxx,ans[j]-cost[i]*ma[i][j]);
if (Minn==-||Minn>Maxx)Minn=Maxx;
}
printf("%d",Minn);
}
int main()
{
freopen("transport.in","r",stdin);
freopen("transport.out","w",stdout);
scanf("%d%d",&n,&m);
for (int i=;i<=n-;i++)
{
scanf("%d%d%d",&a,&b,&vv);
add(a,b,vv);
add(b,a,vv);
}
fa[]=;
dfs();
for (int i=;i<=m;i++)scanf("%d%d",&u[i],&v[i]);
if (m==)work1();else work2();
}
那么剩下40分呢?
最远的最短显然是二分权值
于是使用树链剖分给每个点打上记号顺便可以求求lca
二分check时
开始时借鉴了LXF队长的思想:用线段树给每个大于mid的路径的都打上标记,假设有s个,然后nlogn释放所有标记,o(n)查找一个点被s条路径经过且最大
然后95分跪于最后一个点 将近2s
所以就想到了差分 既然要释放标记不如直接差分
最后一个点卡时过
优化一:读入优化
优化二:记忆化 同一个s的话所能求到的最大点是一定的
为什么是取s条路径的交呢?
证明:
因为如果只取s-1条那么必然有一个路径是无法被减到mid以下。
然后时间复杂度 树链剖分(logn)*二分(logn)*枚举边(n)=nlognlogn
空间复杂度 0(n)
#include<cstdio>
#include<algorithm>
#include<cstring>
const int maxn=;
struct range {
int x,y,len;
}d[maxn];
bool cmp(range x,range y){return x.len>y.len;}
int root,n,m,x,y,tot,next[maxn],last[maxn],e[maxn],dep[maxn],fa[maxn],size[maxn],son[maxn],top[maxn],pos[maxn];
int pos2[maxn],val[maxn],cost[maxn],MAX[maxn],dist[maxn],s[maxn],node,ans,q[maxn];
int read()//优化之一
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void add(int x,int y,int v)
{
next[++tot]=last[x];
last[x]=tot;
val[tot]=v;
e[tot]=y;
}
void dfs1(int x)
{
dep[x]=dep[fa[x]]+;
size[x]=;
for (int i=last[x];i;i=next[i])
{
int v=e[i];
if (v==fa[x])continue;
fa[v]=x;
dist[v]=dist[x]+val[i];
cost[v]=val[i];
dfs1(v);
size[x]+=size[v];
if (size[v]>size[son[x]])son[x]=v;
}
}
void dfs2(int x,int tp)//树链剖分
{
top[x]=tp;pos[x]=++node;pos2[node]=cost[x];
if (son[x]==)return;
dfs2(son[x],tp);
for (int i=last[x];i;i=next[i])
{
int v=e[i];
if (v==fa[x]||v==son[x])continue;
dfs2(v,v);
}
}
int query(int x,int y)//lca
{
int a=x,b=y;
while (top[a]!=top[b])
{
if (dep[top[a]]<dep[top[b]])std::swap(a,b);
a=fa[top[a]];
}
if (dep[a]<dep[b])return a;else return b;
}
void work(int x,int y)//差分
{
int a=x,b=y;
while (top[a]!=top[b])
{
if (dep[top[a]]<dep[top[b]])std::swap(a,b);
s[pos[top[a]]]+=;s[pos[a]+]-=;
a=fa[top[a]];
}
if (a==b)return;
if (dep[a]>dep[b]) std::swap(a,b);
s[pos[a]+]+=;s[pos[b]+]-=;;
}
int check(int mid)
{
int sz=;
while (d[sz+].len>mid)sz++;
if (q[sz]!=)return q[sz];//优化之一 记忆化
std::memset(s,,sizeof(s));
for (int i=;i<=sz;i++)work(d[i].x,d[i].y);
int Maxx=,tott=;
for (int i=;i<=n;i++){tott+=s[i];if (tott==(sz))Maxx=std::max(Maxx,pos2[i]);}
q[sz]=Maxx;
return Maxx;
}
int main()
{
n=read();m=read();
for (int i=;i<n;i++)
{
int v;
x=read();y=read();v=read();
add(y,x,v);add(x,y,v);
}
dfs1();
dfs2(,);
for (int i=;i<=m;i++)
{
d[i].x=read();d[i].y=read();
d[i].len=dist[d[i].x]+dist[d[i].y]-*dist[query(d[i].x,d[i].y)];
}
std::sort(d+,d++m,cmp);
int l=,r=d[].len;
while (l<=r)
{
int mid=(l+r)>>;
if (d[].len-check(mid)>mid)
{
l=mid+;
}else r=mid-,ans=mid;
}
printf("%d",ans);
return ;
}
 ps:一百多行。。。
 

NOIP 2015 BZOJ 4326 运输计划 (树链剖分+二分)的更多相关文章

  1. 【BZOJ-4326】运输计划 树链剖分 + 树上差分 + 二分

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

  2. hdu4729 树链剖分+二分

    An Easy Problem for Elfness Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65535/65535 K (J ...

  3. BZOJ 4326 运输计划

    二分答案+树链剖分+树上差分 我们假设x是最小的花费,可以想到给定x,所有运输计划中花费大于x的计划必须经过虫洞,且最长的一条的花费减去虫洞所在边的花费要小于等于x 那么对于x,虫洞所在的位置肯定是确 ...

  4. BZOJ 4326 树链剖分+二分+差分+记忆化

    去年NOIP的时候我还不会树链剖分! 还是被UOJ 的数据卡了一组. 差分的思想还是很神啊! #include <iostream> #include <cstring> #i ...

  5. BZOJ 2243: [SDOI2011]染色 [树链剖分]

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6651  Solved: 2432[Submit][Status ...

  6. [BZOJ - 2819] Nim 【树链剖分 / DFS序】

    题目链接: BZOJ - 2819 题目分析 我们知道,单纯的 Nim 的必胜状态是,各堆石子的数量异或和不为 0 .那么这道题其实就是要求求出树上的两点之间的路径的异或和.要求支持单点修改. 方法一 ...

  7. BZOJ.4515.[SDOI2016]游戏(树链剖分 李超线段树)

    BZOJ 洛谷 每次在路径上加的数是个一次函数,容易看出是树剖+李超线段树维护函数最小值.所以其实依旧是模板题. 横坐标自然是取个确定的距离标准.取每个点到根节点的距离\(dis[i]\)作为\(i\ ...

  8. BZOJ 2243 染色(树链剖分好题)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 7971  Solved: 2990 [Submit][Stat ...

  9. BZOJ 3531 [Sdoi2014]旅行 树链剖分+动态开点线段树

    题意 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我们用 ...

随机推荐

  1. 通过setDB2Client*来方便的使用TRACE调优jdbc程序

    一般来说通过TRACE的report来分析DDF的性能问题的话,基本对DBA都是噩梦一样.因为所有的Thread都是通过DDF一个类型的Thread,所以不管你怎么分类,看Accounting rep ...

  2. 【过程改进】 windows下jenkins常见问题填坑

    没有什么高深的东西,1 2天的时间大多数人都能自己摸索出来,这里将自己遇到过的问题分享出来避免其他同学再一次挖坑. 目录 1. 主从节点 2. Nuget自动包还原 3. powershell部署 4 ...

  3. 五、Standard Controllers

    1.standardController:标准的controller 是同页面的standard Object的界面button的功能和逻辑是一样的<apex:page standardCont ...

  4. Hadoop日志文件分析系统

    Hadoop日志分析系统 项目需求: 需要统计一下线上日志中某些信息每天出现的频率,举个简单的例子,统计线上每天的请求总数和异常请求数.线上大概几十台 服务器,每台服务器大概每天产生4到5G左右的日志 ...

  5. mongoDB windows安装

    http://www.mongodb.org/ mongodb的官方文档. http://www.cnblogs.com/lipan/archive/2011/03/08/1966463.html  ...

  6. Ubuntu16.04搭建LAMP架构服务器

     安装Apache: weirubo@weirubo-VirtualBox:~$ sudo apt-get install apache2 查看Apache版本: weirubo@weirubo-Vi ...

  7. 原生JS--COOKIE

    原生JS--COOKIE: COOKIE基础及应用:1.什么是COOKIE==>页面用来保存信息,比如:自动登录,记住用户名2.COOKIE的特性:  --同一个网站中,所有的页面共享同一套co ...

  8. 怎么简单获取input file 选中的图片,并在一个div的img里面赋值src实现预览?

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs ...

  9. [问题2015S06] 复旦高等代数 II(14级)每周一题(第七教学周)

    [问题2015S06]  设 \(V\) 是数域 \(\mathbb{K}\) 上的 \(n\) 维线性空间, \(\varphi\) 是 \(V\) 上的线性变换. (1) 求证: 对任一非零向量 ...

  10. 使用XML定制Ribbon的一点小前奏(稍微再进一步的理解XML)

    定制文档级Ribbon界面的实现思路: 1.excel的文件使用rar+xml的形式保存在本地. 2.用压缩软件打开文件,以规范的格式直接编缉或添加xml文件 3.使用excel文件时,主程序会解析x ...