NOIP2015运输计划(二分答案)
题目描述
公元2044年,人类进入了宇宙纪元。
L国有n个星球,还有n-1条双向航道,每条航道建立在两个星球之间,这n-1条航道连通了L国的所有星球。
小P掌管一家物流公司,该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从ui号星球沿最快的宇航路径飞行到vi号星球去。显然,飞船驶过一条航道是需要时间的,对于航道j,任意飞船驶过它所花费的时间为tj,并且任意两艘飞船之间不会产生任何干扰。
为了鼓励科技创新,L国国王同意小P的物流公司参与L国的航道建设,即允许小P把某一条航道改造成虫洞,飞船驶过虫洞不消耗时间。
在虫洞的建设完成前小P的物流公司就预接了m个运输计划。在虫洞建设完成后,这m个运输计划会同时开始,所有飞船一起出发。当这m个运输计划都完成时,小P的物流公司的阶段性工作就完成了。
如果小P可以自由选择将哪一条航道改造成虫洞,试求出小P的物流公司完成阶段性工作所需要的最短时间是多少?
输入格式
第一行包括两个正整数n、m,表示L国中星球的数量及小P公司预接的运输计划的数量,星球从1到n编号。
接下来n-1行描述航道的建设情况,其中第i行包含三个整数ai, bi和ti,表示第i条双向航道修建在ai与bi两个星球之间,任意飞船驶过它所花费的时间为ti。
接下来m行描述运输计划的情况,其中第j行包含两个正整数uj和vj,表示第j个运输计划是从uj号星球飞往vj号星球。
输出格式
共1行,包含1个整数,表示小P的物流公司完成阶段性工作所需要的最短时间。
input
6 3
1 2 3
1 6 4
3 1 7
4 3 6
3 5 5
3 6
2 5
4 5
output
11
样例说明
将第1条航道改造成虫洞:则三个计划耗时分别为:11、12、11,故需要花费的时间为12。
将第2条航道改造成虫洞:则三个计划耗时分别为:7、15、11,故需要花费的时间为15。
将第3条航道改造成虫洞:则三个计划耗时分别为:4、8、11,故需要花费的时间为11。
将第4条航道改造成虫洞:则三个计划耗时分别为:11、15、5,故需要花费的时间为15。
将第5条航道改造成虫洞:则三个计划耗时分别为:11、10、6,故需要花费的时间为11。
故将第3条或第5条航道改造成虫洞均可使得完成阶段性工作的耗时最短,需要花费的时间为11。
限制与约定

解题思路:
首先考虑一下暴力,在n,m都小于3000时,先将两点间的边权值转化为深度较大的点的权值,利用朴素LCA求出两点间的耗费时间,再枚举删去哪一点枚举m中答案,更新即可
时间复杂度O(n*m),期望得分60分
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long lnt;
struct pnt{
int hd;
int no;
int fa;
int ol;
int dp;
lnt val;
}p[];
struct ent{
int twd;
int lst;
lnt tim;
}e[];
int cnt;
int n,m;
lnt ans=0x7f7f7f7f7f7f7f7fll;
int u[];
int v[];
int tf[];
int hv[][];
void ade(int f,int t,lnt y)
{
cnt++;
e[cnt].twd=t;
e[cnt].lst=p[f].hd;
p[f].hd=cnt;
e[cnt].tim=y;
}
void dfs(int x,int f)
{
p[x].dp=p[f].dp+;
p[x].fa=f;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to!=f)
{
p[to].val=e[i].tim;
dfs(to,x);
}
}
return ;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)
{
int a,b;
lnt c;
scanf("%d%d%lld",&a,&b,&c);
ade(a,b,c);
ade(b,a,c);
}
dfs(,);
for(int i=;i<=m;i++)
{
scanf("%d%d",&u[i],&v[i]);
}
if(m==)
{
lnt mtmp=;
lnt mins=;
int x=u[];
int y=v[];
if(p[x].dp<p[y].dp)
swap(x,y);
while(p[x].dp!=p[y].dp)
{
mtmp+=p[x].val;
mins=max(mins,p[x].val);
x=p[x].fa;
}
if(x==y)
{
printf("%lld\n",mtmp-mins);
return ;
}
while(x!=y)
{
mins=max(mins,p[x].val);
mins=max(mins,p[y].val);
mtmp+=p[x].val;
x=p[x].fa;
mtmp+=p[y].val;
y=p[y].fa;
}
printf("%lld\n",mtmp-mins);
return ;
}
for(int i=;i<=m;i++)
{
lnt mtmp=;
int x=u[i];
int y=v[i];
if(p[x].dp<p[y].dp)
swap(x,y);
while(p[x].dp!=p[y].dp)
{
hv[i][x]=;
mtmp+=p[x].val;
x=p[x].fa;
}
if(x==y)
{
tf[i]=mtmp;
continue;
}
while(x!=y)
{
hv[i][x]=;
hv[i][y]=;
mtmp+=p[x].val;
x=p[x].fa;
mtmp+=p[y].val;
y=p[y].fa;
}
tf[i]=mtmp;
}
for(int i=;i<=n;i++)
{
lnt maxs=;
for(int j=;j<=m;j++)
{
maxs=max(maxs,tf[j]-(lnt)hv[j][i]*p[i].val);
}
ans=min(ans,maxs);
}
printf("%lld\n",ans);
return ;
}
正解:
二分答案+树上打差分
将计划排序。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long lnt;
struct pnt{
int fa;
int dp;
int hd;
int ola;
int sgrl;
lnt dis;
}p[];
struct ent{
int twd;
int lst;
lnt vls;
}e[];
struct qnt{
int u;
int v;
lnt dtc;
}q[];
int n,m;
int cnt;
int ont;
int lsd;
int top;
int old[][];
int lg[];
int lns[];
int lfs[];
bool cmp(qnt x,qnt y)
{
return x.dtc>y.dtc;
}
void ade(int f,int t,lnt v)
{
cnt++;
e[cnt].twd=t;
e[cnt].lst=p[f].hd;
e[cnt].vls=v;
p[f].hd=cnt;
}
void dfs_build(int x,int f)
{
old[][++ont]=x;
p[x].fa=f;
p[x].dp=p[f].dp+;
p[x].ola=ont;
bool flag=;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to!=f)
{
flag=false;
p[to].dis=p[x].dis+e[i].vls;
dfs_build(to,x);
old[][++ont]=x;
}
}
if(flag)
{
lfs[++lsd]=x;
}
}
void Tr_dfs(int x,int f)
{
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to!=f)
{
Tr_dfs(to,x);
p[x].sgrl+=p[to].sgrl;
}
}
return ;
}
int rmaxs(int x,int y)
{
return p[x].dp>p[y].dp?y:x;
}
int lca(int x,int y)
{
if(p[x].ola>p[y].ola)
swap(x,y);
int lgg=lg[p[y].ola-p[x].ola+];
return rmaxs(old[lgg][p[x].ola],old[lgg][p[y].ola-(<<lgg)+]);
}
int Ccl(int agc)
{
int x=;
while(agc<q[x+].dtc)x++;
if(lns[x])return lns[x];
for(int i=;i<=n;i++)
p[i].sgrl=;
for(int i=;i<=x;i++)
{
p[q[i].u].sgrl++;
p[q[i].v].sgrl++;
p[lca(q[i].v,q[i].u)].sgrl-=;
}
Tr_dfs(,);
lnt ans=;
for(int i=;i<=n;i++)
{
if(p[i].sgrl==x)
{
ans=max(ans,p[i].dis-p[p[i].fa].dis);
}
}
lns[x]=ans;
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)
{
int x,y;
int z;
scanf("%d%d%d",&x,&y,&z);
ade(x,y,z);
ade(y,x,z);
}
for(int i=;i<=*n;i++)
{
lg[i]=lg[i/]+;
}
dfs_build(,);
for(int i=;i<=;i++)
for(int j=;j+(<<i)-<=ont;j++)
old[i][j]=rmaxs(old[i-][j],old[i-][j+(<<i-)]);
for(int i=;i<=m;i++)
{
scanf("%d%d",&q[i].u,&q[i].v);
q[i].dtc=p[q[i].u].dis+p[q[i].v].dis-*p[lca(q[i].v,q[i].u)].dis;
}
sort(q+,q+m+,cmp);
int l=;
int r=q[].dtc;
int ans;
while(l<=r)
{
int mid=(l+r)>>;
if(q[].dtc-Ccl(mid)>mid)l=mid+;
else{
ans=mid;
r=mid-;
}
}
printf("%d\n",ans);
return ;
}
NOIP2015运输计划(二分答案)的更多相关文章
- 【bzoj4326】[NOIP2015]运输计划 二分答案+LCA
题目描述 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家物流公司, 该 ...
- BZOJ 4326 NOIP2015 运输计划 (二分+树上差分)
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1930 Solved: 1231[Submit][Statu ...
- [luogu]P2680 运输计划[二分答案][树上差分]
[luogu]P2680 [NOIP2015]运输计划 题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n ...
- loj2425 「NOIP2015」运输计划[二分答案+树上差分]
看到题意最小化最长路径,显然二分答案,枚举链长度不超过$\text{mid}$,然后尝试检验.````` 检验是否存在这样一个边置为0后,全部链长$\le\text{mid}$,其最终目标就是.要让所 ...
- luogu P2680 运输计划 (二分答案+树上差分)
题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条航道建立在两个星球之间 ...
- vijos 运输计划 - 二分答案 - 差分 - Tarjan
Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家 ...
- BZOJ 4326: NOIP2015 运输计划(二分,树上差分)
Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1945 Solved: 1243[Submit][Status][Discuss] Descript ...
- 运输计划[二分答案 LCA 树上差分]
也许更好的阅读体验 \(\mathcal{Description}\) 原题链接 概括一下题意 给一颗有\(n\)个点带边权的树,有\(m\)个询问,每次询问\(u,v\)两点间的权值和,你可以将树中 ...
- NOIP2015 运输计划 - 二分 + 树链剖分 / (倍增 + 差分)
BZOJ CodeVS Uoj 题目大意: 给一个n个点的边带权树,给定m条链,你可以选择树中的任意一条边,将它置为0,使得最长的链长最短. 题目分析: 最小化最大值,二分. 二分最短长度mid,将图 ...
- cogs2109 [NOIP2015] 运输计划
cogs2109 [NOIP2015] 运输计划 二分答案+树上差分. STO链剖巨佬们我不会(太虚伪了吧 首先二分一个答案,下界为0,上界为max{路径长度}. 然后判断一个答案是否可行,这里用到树 ...
随机推荐
- Spring可扩展Schema标签
基于Spring可扩展Schema提供自己定义配置支持 http://blog.csdn.net/cutesource/article/details/5864562 WARN : org.sprin ...
- Cocos2d-x第三方类库不支持arm64的问题解决(64位架构)
32位能够兼容64位操作系统. ipad mini2 64位编译有问题. 各种第三方库不支持64位操作系统. 设置build setting 直接上图:
- How to test Heat (by quqi99)
作者:张华 发表于:2015-12-19版权声明:能够随意转载.转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 (http://blog.csdn.net/quqi99 ) Heat ...
- QThread 爬坑之旅(三种办法解决QObject: Cannot create children for a parent that is in a different thread)
Cannot create children for a parent that is in a different thread. 在Qt的官方文档,大家知道有两种方式使用QThread. You ...
- 浏览器下载img标签Base64图片
https://blog.csdn.net/qq_42076140/article/details/82113622 原文地址 <a href="javascript:downl ...
- SpringMVC+MyBatis (druid、logback)
数据库连接池是阿里巴巴的druid.日志框架式logback 1.整合SpringMVCspringMybatis-servlet.xml: <?xml version="1.0&qu ...
- SQL大小写金额转换
--功能: 用于将小写的数值翻译成大写的字符串(支持到分,即小数点后两位) --入口参数:@decNum------数字型变量 --返回:字符串 --举例:select dbo.fn_ChnMoney ...
- 利用CORS实现跨域请求--转
原文地址:http://newhtml.net/using-cors/ 跨域请求一直是网页编程中的一个难题,在过去,绝大多数人都倾向于使用JSONP来解决这一问题.不过现在,我们可以考虑一下W3C中一 ...
- Network Stack : CookieMonster
CookieMonster The CookieMonster is the class in Chromium which handles in-browser storage, managem ...
- 【Codeforces Round #460 (Div. 2) A】 Supermarket
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 就是让你求m*(ai/bb)的最小值 [代码] #include <bits/stdc++.h> #define dou ...