题目描述

公元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运输计划(二分答案)的更多相关文章

  1. 【bzoj4326】[NOIP2015]运输计划 二分答案+LCA

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

  2. BZOJ 4326 NOIP2015 运输计划 (二分+树上差分)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1930  Solved: 1231[Submit][Statu ...

  3. [luogu]P2680 运输计划[二分答案][树上差分]

    [luogu]P2680 [NOIP2015]运输计划 题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n ...

  4. loj2425 「NOIP2015」运输计划[二分答案+树上差分]

    看到题意最小化最长路径,显然二分答案,枚举链长度不超过$\text{mid}$,然后尝试检验.````` 检验是否存在这样一个边置为0后,全部链长$\le\text{mid}$,其最终目标就是.要让所 ...

  5. luogu P2680 运输计划 (二分答案+树上差分)

    题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条航道建立在两个星球之间 ...

  6. vijos 运输计划 - 二分答案 - 差分 - Tarjan

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

  7. BZOJ 4326: NOIP2015 运输计划(二分,树上差分)

    Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1945  Solved: 1243[Submit][Status][Discuss] Descript ...

  8. 运输计划[二分答案 LCA 树上差分]

    也许更好的阅读体验 \(\mathcal{Description}\) 原题链接 概括一下题意 给一颗有\(n\)个点带边权的树,有\(m\)个询问,每次询问\(u,v\)两点间的权值和,你可以将树中 ...

  9. NOIP2015 运输计划 - 二分 + 树链剖分 / (倍增 + 差分)

    BZOJ CodeVS Uoj 题目大意: 给一个n个点的边带权树,给定m条链,你可以选择树中的任意一条边,将它置为0,使得最长的链长最短. 题目分析: 最小化最大值,二分. 二分最短长度mid,将图 ...

  10. cogs2109 [NOIP2015] 运输计划

    cogs2109 [NOIP2015] 运输计划 二分答案+树上差分. STO链剖巨佬们我不会(太虚伪了吧 首先二分一个答案,下界为0,上界为max{路径长度}. 然后判断一个答案是否可行,这里用到树 ...

随机推荐

  1. 赵雅智_运用Bitmap和Canvas实现图片显示,缩小,旋转,水印

    上一篇已经介绍了Android种Bitmap和Canvas的使用,以下我们来写一个详细实例 http://blog.csdn.net/zhaoyazhi2129/article/details/321 ...

  2. JavaWeb简单介绍

    服务器端编程 技术种类 Servlet JSP Struts Spring Hibernate EJB Web Service Web服务器 IIS Apache Tomcat (提供对JSP和Ser ...

  3. hdoj--1034--Hidden String(dfs)

    Hidden String Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) ...

  4. XDoclet学习

    XDoclet可以通过你在java源代码中的一些特殊的注释信息,自动为你生成配置文件.源代码等等,例如web.ejb的部署描述文件.为你生成struts的struts-config.xml配置文件.j ...

  5. [ DB ] [ SQL ] [ SQL Server ] MS SQL 建立暫存表格 temp table - 轉載

    範例 SQL: IF OBJECT_ID(N'tempdb.dbo.#tmp_checkStatusCount', N'U') IS NOT NULL DROP TABLE #tmp_checkSta ...

  6. HTTP 与 HTTPS

    https就是http和TCP之间有一层SSL层,这一层的实际作用是防止钓鱼和加密. 防止钓鱼通过网站的证书,网站必须有CA证书,证书类似于一个解密的签名. 另外是加密,加密需要一个密钥交换算法,双方 ...

  7. WCF项目启动时错误处理

    1. 原因:启动有wcf服务的项目时,报错,是因为wcf的服务没有启动. 解决办法:启动wcf的服务端口,127.0.0:4000,错误消失.

  8. c#同步上下文SynchronizationContext学习笔记

    提供在各种同步模型中传播同步上下文的基本功能.同步上下文的工作就是确保调用在正确的线程上执行. 同步上下文的基本操作 Current 获取当前同步上下文 var context = Synchroni ...

  9. 通过域 组策略禁用U盘(只允许部份许可U盘可在客户端读取)

    U盘禁用设置步骤: 1.客户端 注册表修改,USBStor  的start改为4 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UsbSto ...

  10. layui图片懒加载-loading占位图

    前言 使用layui的图片懒加载,发现未加载的图片没有loading占位图,显示的是裂图,看着不是很好.找了一些解决方法我统一记录一下. layui图片懒加载使用方法 layui.use(’flow’ ...