[BZOJ]3246: [Ioi2013]Dreaming 暴力乱搞
来源:互联网 发布:粒子群算法工具箱使用 编辑:程序博客网 时间:2024/05/21 13:58
Description
Serpent(水蛇)生活的地方有N个水坑,编号为0,…,N - 1,有M条双向小路连接这些水坑。每两个水坑之间至多有一条路径(路径包含一条或多条小路)相互连接,有些水坑之间根本无法互通(即M ≤ N-1 )。Serpent走过每条小路需要一个固定的天数,不同的小路需要的天数可能不同。Serpent的朋友袋鼠希望新修 N - M - 1条小路,让Serpent可以在任何两个水坑间游走。袋鼠可以在任意两个水坑之间修路,Serpent通过每条新路的时间都是L天。袋鼠希望找到一种修路方式使得修路之后Serpent在每两个水坑之间游走的最长时间最短。
举例说明
上图中有12个水坑8条小路( N = 12, M = 8)。假如L = 2 ,即Serpent通过任何一条新路都需要2天。那么,袋鼠可以修建3条新路:
水坑1和水坑2之间;
水坑1和水坑6之间;
水坑4和水坑10之间。
上图显示了修路后的最终状态。从水坑0走到水坑11的时间最长,需要18天。这是 最佳结果,无论袋鼠如何选择修路方式,总会存在一些水坑对,Serpent需要18天 或者更长时间从其中一个走到另一个。
题解:
首先预处理出每个点的作为起点的最长路和次长路,然后根据这个就可以求出每棵树哪个点的最长路最短,那么若其它树与这棵树相连,就连这个点(这个显然),然后对每棵树的这个点的最长路从大到小排序,然后两两合并(这个自己画画就知道正确性显然了),维护新树的最长路最短路即可。
代码:
#include<bits/stdc++.h>using namespace std;#define LL long long#define pa pair<int,int>const int Maxn=500010;int n,m;LL l;struct Edge{int y,next;LL d;}e[Maxn<<1];int last[Maxn],len=0;void ins(int x,int y,LL d){int t=++len;e[t].y=y;e[t].d=d;e[t].next=last[x];last[x]=t;}LL mx1[Maxn],mx2[Maxn],tmp;bool vis[Maxn];int p[Maxn],lp=0,ansp;int rt;void dfs1(int x,int fa){ mx1[x]=0;vis[x]=true; for(int i=last[x];i;i=e[i].next) { int y=e[i].y; if(y==fa)continue; dfs1(y,x); if(e[i].d+mx1[y]>=mx1[x]) { mx2[x]=mx1[x]; mx1[x]=e[i].d+mx1[y]; } else if(e[i].d+mx1[y]>mx2[x])mx2[x]=e[i].d+mx1[y]; }}LL ans=0;void dfs2(int x,int fa,LL d){ LL tot=0; if(fa) { if(mx1[fa]==d+mx1[x]) { if(mx2[fa]+d>=mx1[x]) { mx2[x]=mx1[x]; mx1[x]=mx2[fa]+d; } else if(mx2[fa]+d>mx2[x])mx2[x]=mx2[fa]+d; } else { if(mx1[fa]+d>=mx1[x]) { mx2[x]=mx1[x]; mx1[x]=mx1[fa]+d; } else if(mx1[fa]+d>mx2[x])mx2[x]=mx1[fa]+d; } } if(mx1[x]<tmp)tmp=mx1[x],ansp=x; ans=max(ans,mx1[x]+mx2[x]); for(int i=last[x];i;i=e[i].next) { int y=e[i].y; if(y==fa)continue; dfs2(y,x,e[i].d); }}bool cmp(int x,int y){return mx1[x]>mx1[y];}int main(){ scanf("%d%d%lld",&n,&m,&l); for(int i=1;i<=n;i++)vis[i]=false,mx2[i]=0; for(int i=1;i<=m;i++) { int x,y;LL d; scanf("%d%d%lld",&x,&y,&d);x++;y++; ins(x,y,d);ins(y,x,d); } for(int i=1;i<=n;i++) if(!vis[i]) { tmp=(1LL<<60); dfs1(i,0);dfs2(i,0,0); p[++lp]=ansp; } sort(p+1,p+1+lp,cmp); for(int i=2;i<=lp;i++) { int t1=p[i-1],t2=p[i]; ans=max(max(mx1[t1]+mx2[t1],mx1[t2]+mx2[t2]),mx1[t1]+mx1[t2]+l); LL tmp1=mx1[t1]; if(l+mx1[t2]>=mx1[t1]) { mx2[t1]=mx1[t1]; mx1[t1]=l+mx1[t2]; } else if(l+mx1[t2]>mx2[t1])mx2[t1]=l+mx1[t2]; if(l+tmp1>=mx1[t2]) { mx2[t2]=mx1[t2]; mx1[t2]=l+tmp1; } else if(l+tmp1>mx2[t2])mx2[t2]=l+tmp1; if(mx1[t1]<mx1[t2])p[i]=t1; else p[i]=t2; } printf("%lld",ans);}
阅读全文
1 0
- [BZOJ]3246: [Ioi2013]Dreaming 暴力乱搞
- 【BZOJ】3246 [Ioi2013]Dreaming
- bzoj 3246: [Ioi2013]Dreaming
- bzoj 3246 [Ioi2013] Dreaming 题解
- bzoj 3246: [Ioi2013]Dreaming 树形dp+树的直径
- 【bzoj3246】 Ioi2013—Dreaming
- [bzoj3246] [Ioi2013]Dreaming
- [暴力 乱搞] BZOJ 2338 [HNOI2011]数矩形
- [乱搞 暴力] BZOJ 1142 [POI2009]Tab
- BZOJ 3246 IOI 2013 Dreaming 树形DP
- 【BZOJ 2120】 数颜色 (乱搞分块,直指暴力)
- [乱搞 暴力 并查集] BZOJ 3563 DZY Loves Chinese
- BZOJ 3922: Karin的弹幕 线段树 暴力乱搞
- [二分答案 贪心] BZOJ 3248 [ioi2013]robots
- 【暴力乱搞】HDU4473 Exam
- Dreaming
- dreaming
- 【bzoj 2433】【NOI 2011 D1T2】 智能车比赛 想法乱搞+暴力
- springboot thymeleaf + vue
- Android Studio 第三方库依赖集锦
- Mysql中的collation stage1-9
- Struts2配置XML基本格式
- File类
- [BZOJ]3246: [Ioi2013]Dreaming 暴力乱搞
- 数据库索引到底是什么,是怎样工作的?5
- 用python字典写的一个简单的通讯录小系统
- 关于JAVA语言环境搭建
- Linux上使用Qt Creator进行C/C++开发
- 用C语言实现走迷宫
- log4j日志封装说明—slf4j对于log4j的日志封装-正确获取调用堆栈
- hibernate 配置文件
- Java并发之线程同步