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{路径长度}. 然后判断一个答案是否可行,这里用到树 ...
随机推荐
- swift 笔记 (十一) —— 方法(类,结构体,枚举)
Methods (方法) 实例方法(Instance Methods) 我认为看到这里.我们唯能八一八的就是swift的自做主张的行为了,反正它就是会以各种方式帮助我们来完毕让代码看起来非常奇怪的事情 ...
- 19.浏览器Window服务($window)
转自:https://www.cnblogs.com/best/tag/Angular/ 引用浏览器的window对象.默认浏览器的window是全局的根对象. 示例代码: <!DOCTYPE ...
- SQL函数-str()
1 str()函数用于将数值类型数据转换未字符类型. 2 str()函数语法 select str(数字类型的表达式[,表达式总长度][,小数点后面的位数]) 表达式总长度和小数点后面的位数为可选择参 ...
- Debian9.5 配置x11vnc远程桌面
x11vnc是一个VNC服务器,它允许用户远程查看并用任何VNC查看器与真实的X显示器(即与物理监视器,键盘和鼠标相对应的显示器)进行交互.虽然它的原作者Karl Runge不再开发,但LibVNC和 ...
- CentOS6.x操作系统自带的 DM Multipath(DMMP)多路径软件配置说明。
CentOS系统下的多路径软件是操作系统自带的 DM Multipath(DMMP)工具.------------------------------------------------------- ...
- OpenSUSE Leap 42.3 安装java(Oracle jre)
一.安装1.从Oracle官网下载jre-8u161-linux-x64.rpm安装包(下载与浏览器位数一样) 2.安装: openSUSE:/home/pipci # rpm -ivh jre-8u ...
- HH生病了(hpu1136)
HH生病了 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 324 Solved: 90 [Submit][Status][Web Board] De ...
- 【推荐】适合本科生的网络公开课(MOOC为主),不断更新……
题记:身在海大(湛江),是幸运还是不幸,每一个人有自己的定义.人生不能再来一次,唯有把握当下.提高自己,才可能在不能拼爹的年代靠自身实力前行.或许,我们做不了富二代.但我们每一个人.都有机会成为富二代 ...
- 用YourAPP开发网络状态提醒应用
如今的通信真是方便,走到哪里都有网络.Wifi的利用已经到了很普及的程度.即使走到没有wifi信号的地方,利用手机信号也能上网.(若是连手机信号都没有,那就没办法了) 智能手机的使用也大慷慨面了各个年 ...
- webgoat 7.1 实战指南
WSASP中文文档参考链接: http://www.owasp.org.cn/owasp-project/2017-owasp-top-10 OWASP Top 10 2017中文版V1.3http: ...