[NOIP2015提高组]运输计划

题目:BZOJ4326、洛谷P2680、Vijos P1983、UOJ#150、codevs4632、codevs5440。

题目大意:有一棵带权树,有一些运输计划,第i个运输计划从ai到bi,耗时为ai到bi的距离,所有运输计划一起开始。现在可以把一条边权变成0,求最终运输计划最短要多少时间。

解题思路:标算是树剖,然而我并不会……

我的方法是LCA+二分+树上差分。

首先LCA,求出每个运输计划的长度,可一遍dfs求出每个节点到根的距离dist,则a到b的长度为dist[a]+dist[b]-(dist[lca(a,b)]<<1)。

接着二分答案,然后判断答案可行性。

对于每一个答案,我们要找的是所有长度大于当前答案的运输计划的公共边,因为只有所有长度大于当前答案的运输计划全部变成小于等于当前答案,当前答案才可行。

用树上差分(不懂请百度)。我们用s[i]记录i到它父亲这条边有多少计划经过。

对于每个运输计划,如果长度大于当前答案,我们给s[a]+1,s[b]+1,s[lca(a,b)]-2,因为我们要统计的是边,所以对于两个点,lca(a,b)对应的边实际是没有走到的,所以-2。

差分完后判断答案可行性即可。

我用倍增时间复杂度为$O(m\log_2 n+(n+m)\log_2 len)$,len为运输计划的最大长度。

但常数巨大,1s很容易被卡,因此有些地方还过不掉。例如我在UOJ上就被卡97。但在时限较宽或数据较弱的地方还是能AC的。

C++ Code:

%:pragma GCC optimize(2)
#include<cstdio>
#include<cctype>
#include<cstring>
using namespace std;
char buf[10700005];
int bufpos,n,m,head[300001],deep[300001],p[300001][21],dist[300001],s[300001],fa_edge[300001],mx,now;
struct edge{int to,dis,nxt;
}e[600003];
struct que{int a,b,len,LCA;
}f[300001];
inline int max(int a,int b){return(a>b)?a:b;}
inline int readint(){char c=buf[bufpos++];for(;!isdigit(c);c=buf[bufpos++]);int p=0;for(;isdigit(c);c=buf[bufpos++])p=(p<<3)+(p<<1)+(c^'0');return p;
}
void dfs(int s){for(int i=head[s];i;i=e[i].nxt)if(!deep[e[i].to]){fa_edge[e[i].to]=i;deep[e[i].to]=deep[s]+1;p[e[i].to][0]=s;dist[e[i].to]=dist[s]+e[i].dis;dfs(e[i].to);}
}
int lca(int x,int y){if(deep[x]<deep[y])x^=y^=x^=y;int i;for(i=0;(1<<i)<=deep[x];++i);--i;for(int j=i;j>-1;--j)if(deep[p[x][j]]>=deep[y])x=p[x][j];if(x==y)return x;for(int j=i;j>-1;--j)if(p[x][j]!=-1&&p[x][j]!=p[y][j])x=p[x][j],y=p[y][j];return p[x][0];
}
void updata(int now){for(int i=head[now];i;i=e[i].nxt)if(deep[now]<deep[e[i].to]){updata(e[i].to);s[now]+=s[e[i].to];}
}
bool ok(int ans){memset(s,0,sizeof s);int gz=0;for(int i=1;i<=n;++i)if(f[i].len>ans){++gz;++s[f[i].a];++s[f[i].b];s[f[i].LCA]-=2;}updata(1);for(int i=1;i<=m;++i)if(s[i]==gz&&mx-ans<=e[fa_edge[i]].dis)return true;return false;
}
int main(){buf[fread(buf,1,10700000,stdin)]=bufpos=0;m=readint(),n=readint();for(int i=1;i<m;++i){int from=readint(),to=readint(),dis=readint();now=i<<1;e[now-1]=(edge){to,dis,head[from]};head[from]=now-1;e[now]=(edge){from,dis,head[to]};head[to]=now;}memset(p,-1,sizeof p);dist[1]=0;deep[1]=1;dfs(1);for(int j=1;(1<<j)<=m;++j)for(int i=1;i<=m;++i)if(p[i][j-1]!=-1)p[i][j]=p[p[i][j-1]][j-1];int l=0,r=0,mid;for(int i=1;i<=n;++i){f[i].a=readint();f[i].b=readint();f[i].LCA=lca(f[i].a,f[i].b);r=max(r,f[i].len=dist[f[i].a]+dist[f[i].b]-(dist[f[i].LCA]<<1));}mx=r;++r;while(l<r){mid=l+r>>1;if(ok(mid))r=mid;elsel=mid+1;}printf("%d\n",r);return 0;
}

倍增时间复杂度比较高,我改成用Tarjan求LCA,速度瞬间变快,在UOJ上成功卡了过去。不过codevs4632仍然被卡。

以下为Tarjan代码。

C++ Code:

%:pragma GCC optimize(2)
#include<cstdio>
#include<cctype>
#include<cstring>
using namespace std;
char buf[10700005];
int bufpos,n,m,head[300001],deep[300001],dist[300001],s[300001],fa_edge[300001],mx,now,headq[300001],nq=0;
bool vis[300001];
int fa[300001];
struct edge{int to,dis,nxt;
}e[600003];
struct que{int a,b,len,LCA;
}f[300001];
struct Query{int same,nxt,to,num;bool flag;
}q[600003];
int find(int x){return(fa[x]==x)?x:(fa[x]=find(fa[x]));}
inline int max(int a,int b){return(a>b)?a:b;}
inline int readint(){char c=buf[bufpos++];for(;!isdigit(c);c=buf[bufpos++]);int p=0;for(;isdigit(c);c=buf[bufpos++])p=(p<<3)+(p<<1)+(c^'0');return p;
}
void dfs(int s){for(int i=head[s];i;i=e[i].nxt)if(!deep[e[i].to]){fa_edge[e[i].to]=i;deep[e[i].to]=deep[s]+1;dist[e[i].to]=dist[s]+e[i].dis;dfs(e[i].to);}
}
void tarjan(int root){for(int i=head[root];i;i=e[i].nxt)if(deep[root]<deep[e[i].to]){tarjan(e[i].to);fa[e[i].to]=root;vis[e[i].to]=true;}for(int i=headq[root];i;i=q[i].nxt)if(vis[q[i].to]&&!q[i].flag){q[i].flag=q[q[i].same].flag=true;f[q[i].num].LCA=find(q[i].to);}
}
void updata(int now){for(int i=head[now];i;i=e[i].nxt)if(deep[now]<deep[e[i].to]){updata(e[i].to);s[now]+=s[e[i].to];}
}
bool ok(int ans){memset(s,0,sizeof s);int gz=0;for(int i=1;i<=n;++i)if(f[i].len>ans){++gz;++s[f[i].a];++s[f[i].b];s[f[i].LCA]-=2;}updata(1);for(int i=1;i<=m;++i)if(s[i]==gz&&mx-ans<=e[fa_edge[i]].dis)return true;return false;
}
int main(){buf[fread(buf,1,10700000,stdin)]=bufpos=0;m=readint(),n=readint();for(int i=1;i<m;++i){int from=readint(),to=readint(),dis=readint();now=i<<1;e[now-1]=(edge){to,dis,head[from]};head[from]=now-1;e[now]=(edge){from,dis,head[to]};head[to]=now;fa[i]=i;}fa[m]=m;deep[1]=1;dfs(1);int l=0,r=0,mid;for(int i=1;i<=n;++i){f[i].a=readint();f[i].b=readint();int& x=f[i].a,&y=f[i].b;q[++nq].to=y;q[nq].same=nq+1;q[nq].num=i;q[nq].nxt=headq[x];headq[x]=nq;q[++nq].to=x;q[nq].same=nq-1;q[nq].num=i;q[nq].nxt=headq[y];headq[y]=nq;if(x==y)q[nq].flag=q[nq-1].flag=true,f[i].LCA=x;}tarjan(1);for(int i=1;i<=n;++i)r=max(r,f[i].len=dist[f[i].a]+dist[f[i].b]-(dist[f[i].LCA]<<1));mx=r;++r;while(l<r){mid=l+r>>1;if(ok(mid))r=mid;elsel=mid+1;}printf("%d\n",r);return 0;
}

 

转载于:https://www.cnblogs.com/Mrsrz/p/7635580.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/282221.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

对象存储OSS服务

一、oss是什么 阿里云对象存储服务&#xff08;Object Storage Service&#xff0c;简称OSS&#xff09;为您提供基于网络的数据存取服务。使用OSS&#xff0c;您可以通过网络随时存储和调用包括文本、图片、音频和视频等在内的各种非结构化数据文件。 阿里云OSS将数据文件以…

《Access 2007开发指南(修订版)》一一1.5 什么是数据库对象

本节书摘来自异步社区出版社《Access 2007开发指南(修订版)》一书中的第1章&#xff0c;第1.5节&#xff0c;作者&#xff1a; 【美】Alison Balter&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看。 1.5 什么是数据库对象 Access 2007开发指南(修订版)正如前…

ETL工具kettle的组件--生成记录

今天介绍下kettle的一个比较实用的组件——生成记录&#xff1b;当我们想将一部分文本数据变成数据行&#xff0c;每个字段作为一个数据行的一个列&#xff0c;那么我们可以利用这个组件&#xff1b;它的位置在双击点开根据自己的实际需要进行设置当设置后&#xff0c;可以点击…

Linux学习笔记一

linux  kernel lib module shell tools ls -la&#xff1a; 显示所有文件包括隐藏文件  cat /proc/cpuinfo&#xff1a; 显示cpu信息 man man  /string&#xff1a; 向上搜索string字符串 继续按下小写n向上搜索  ?string&#xff1a; 向下搜索string字符串 继续按下大…

PHP中路由和rewrite的使用

一、场景介绍&#xff1a; 1、简化url地址&#xff0c;方便大家记忆 2、有利于搜索引擎优化 3、安全&#xff08;让用户看不出网站的目录结构&#xff09; 举例&#xff1a;比如我这里将main控制器中的bb方法路由到kk&#xff0c;这样&#xff0c;我们a标签请求跳转到cp.xi…

《NoSQL权威指南》导读

引言 NoSQL权威指南“没有什么会比引入新秩序更难&#xff0c;因为创新者必须要面对那些在旧环境中已经做得很好的对手&#xff0c;以及那些在新环境中做得很好的冷漠者。” ——Niccolo Machiavelli [1] 在过去的几十年&#xff0c;我已经通过Elsevier/Morgan Kaufmann出版社出…

zookeeper的单实例和伪集群部署

原文链接: http://gudaoyufu.com/?p1395 zookeeper工作方式 ZooKeeper 是一个开源的分布式协调服务&#xff0c;由雅虎创建&#xff0c;是 Google Chubby 的开源实现。 分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协 调/通知、集群管…

PHP开发常见功能实现流程

一、pc端网站登录 1、获取并过滤用户提交的用户名和密码以及验证码 2、验证用户提交验证码和session中的验证码是否一致 3、验证用户名是否存在 4、根据用户名获取密码&#xff0c;并校验密码是否一致 5、密码一致&#xff0c;则登录成功&#xff0c;跳转到对应的首页 图示…

七牛直播云服务技术揭秘

以下根据七牛云首席布道师何李石现场演讲内容整理。 直播模型及其实现 一个通用的直播模型一般包括三个模块&#xff1a;主播方、服务器端和播放端。 首先是主播方&#xff0c;它是产生视频流的源头&#xff0c;由一系列流程组成&#xff1a; 第一&#xff0c;通过一定的设备来…

golang 标准库间依赖的可视化展示

简介 国庆看完 << Go 语言圣经 >>,总想做点什么,来加深下印象.以可视化的方式展示 golang 标准库之间的依赖,可能是一个比较好的切入点.做之前,简单搜了下相关的内容,网上也要讨论,但是没有发现直接能拿过来用的.标准库之间,是必然存在依赖关系的,不同库被依赖的程…

Amazon Alexa 新里程碑: 50000 个功能、 20000 种设备、 3500 个品牌

几个月过去&#xff0c;Alexa的设备连接量、活跃度等各项数据又攀升了。昨日&#xff0c;亚马逊智慧家庭副总裁DanielRausch在IFA大会上公布了Alexa的各项数据&#xff1a;全球范围内&#xff0c;Alexa已经拥有50000个功能&#xff0c;与20000种设备相容&#xff0c;并与超过35…

C# 计算耗时的三种方法

概述计算一段程序的耗时是我们在编程中很常见的用法&#xff0c;那这节内容就通过实例的方式来演示几种常用的统计耗时的方法.方法一&#xff1a;stopwatchstatic void Main(string[] args){Stopwatch sw new Stopwatch();sw.Start();Thread.Sleep(999);sw.Stop();Console.Wri…

《HTML5 2D游戏编程核心技术》——第1章,第1.3节特别功能

本节书摘来自华章出版社《HTML5 2D游戏编程核心技术》一书中的第1章&#xff0c;第1.3节特别功能&#xff0c;作者&#xff3b;美&#xff3d; 戴维吉尔里&#xff0c;更多章节内容可以访问云栖社区“华章计算机”公众号查看。 1.3 特别功能 Snail Bait游戏有3个特别的功能&a…

XunSearch的安装和加入服务器开机脚本以及将目录写入系统变量

一、安装xunserach 1、cd ~ 2、wget http://www.xunsearch.com/download/xunsearch-full-latest.tar.bz2 #下载最新xunsearch包 3、tar -xjf xunsearch-full-latest.tar.bz2 #解压xunsearch包 4、cd xunsearch-full-1.4.11/ #进入xunsearch包目录 5、sh setup.sh #执…

dubbo源码解析-zookeeper创建节点

前言 在之前dubbo源码解析-本地暴露中的前言部分提到了两道高频的面试题,其中一道dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,那发布者和订阅者还能通信吗?在上周的dubbo源码解析-zookeeper连接中已经讲到,这周解析的是另一道,即服务提供者能实现失效踢出是根据什么原…

配置mysql为主主复制步骤

mysql版本&#xff1a;mysql-5.6.24-solaris10-sparc-64bit.tar 操作系统&#xff1a;solaris 11g u10 操作用户&#xff1a;使用非root进行操作安装&#xff0c;a路服务器ip地址为192.168.1.1 b路ip地址为192.168.1.2&#xff08;应改为实际ip地址&#xff09; 1&#xff0c;安…

XunSearch的使用

一、项目的配置文件 1、要想使用xunsearch&#xff0c;首先需要进行配置文件的配置。 默认目录在app下&#xff0c;如下面的结构&#xff0c;每一个搜索项目都需要有一个ini文件进行相应的配置。 举例&#xff1a; project.name novel project.default_charset utf-8 serv…

《VMware vSphere设计(原书第2版)》——1.1 什么是设计

本节书摘来自华章出版社《VMware vSphere设计&#xff08;原书第2版&#xff09;》一 书中的第1章&#xff0c;第1.1节&#xff0c;作者&#xff1a;[美] 福布斯格思里&#xff08;Forbes Guthrie&#xff09;斯科特罗威&#xff08;Scott Lowe&#xff09;肯德里克科尔曼&…

SqlKata - 方便好用的 Sql query builder

SqlKata查询生成器是一个用C# 编写的功能强大的Sql查询生成器。它是安全的&#xff0c;与框架无关。灵感来源于可用的顶级查询生成器&#xff0c;如Laravel Query Builder和 Knex&#xff1a;https://knexjs.org/。SqlKata有一个富有表现力的API。它遵循一个干净的命名约定&…

编写高质量代码:改善Java的151个建议四(基本类型)21-30

该书籍PDF下载地址&#xff1a;http://download.csdn.net/download/muyeju/10001473 基本类型有8个&#xff1a;byte&#xff0c;short&#xff0c;int&#xff0c;char&#xff0c;long&#xff0c;double&#xff0c;float&#xff0c;boolean 21.用偶判断&#xff0c;不用奇…