【BZOJ 4016】 [FJOI2014]最短路径树问题
题目链接:
题解:
我就是个智障。明明是道大水题,硬是拖了6h。
关于这道题我唯一想说的就是,记得更新拆分后的子树大小!!!我就是ZZ恒(QwQ。
代码:
#define Troy 10/26/2017
#include <bits/stdc++.h>
using namespace std;
inline int read(){
int s=,k=;char ch=getchar();
while(ch<''|ch>'') ch=='-'?k=-:,ch=getchar();
while(ch>&ch<='') s=s*+(ch^),ch=getchar();
return s*k;
}
const int N=3e5+;
int n,m,K;
struct edges{
int v,w;edges *last;
}edge[N<<],*head[N];int cnt;
inline void push(int u,int v,int w){
edge[++cnt]=(edges){v,w,head[u]};head[u]=edge+cnt;
}
int q[N],dis[N],from[N];
bool vis[N];
inline void dfs(int x){
vis[x]=true;
vector<int > G;
for(edges *i=head[x];i;i=i->last) if(!vis[i->v]&&dis[i->v]==dis[x]+i->w)
G.push_back(i->v);
sort(G.begin(),G.end());
for(int i=;i<G.size();i++){
if(vis[G[i]]) continue;
dfs(G[i]);
from[G[i]]=x;
}
}
inline void spfa(){
int l=,r=;
q[]=;
memset(dis,,sizeof(dis));
dis[]=;
while(l!=r){
int x=q[l++];if(l==N) l=;
for(edges *i=head[x];i;i=i->last){
if(dis[x]+i->w<dis[i->v]){
dis[i->v]=dis[x]+i->w;
if(!vis[i->v])
vis[i->v]=true,q[r++]=i->v;
if(r==N) r=;
}
}
vis[x]=false;
}
dfs();
}
int heavy[N],root,size[N],tot,top,ans=,sum,T[N],t[N],clocks,cnts[N];
inline void dfs(int x,int fa){
size[x]=,heavy[x]=;
for(edges *i=head[x];i;i=i->last)if(i->v!=fa&&(!vis[i->v])){
dfs(i->v,x);
size[x]+=size[i->v];
heavy[x]=max(heavy[x],size[i->v]);
}
heavy[x]=max(heavy[x],tot-size[x]);
if(heavy[x]<=top)
top=heavy[x],root=x;
}
struct node{
int v,w;
inline friend bool operator <(node x,node y){
return size[x.v]<size[y.v];
}
}sons[N];
inline void calc(int x,int fa,int w,int deep){
if(T[K-deep]==clocks){
if(ans<t[K-deep]+w)
ans=t[K-deep]+w,sum=;
if(ans==t[K-deep]+w)
sum+=cnts[K-deep];
}
if(deep+<K)
for(edges *i=head[x];i;i=i->last) if(i->v!=fa&&vis[i->v]==){
calc(i->v,x,w+i->w,deep+);
}
}
inline void update(int x,int fa,int w,int deep){
if(T[deep]==clocks){
if(t[deep]<w)
t[deep]=w,cnts[deep]=;
if(t[deep]==w)
cnts[deep]++;
}
else T[deep]=clocks,t[deep]=w,cnts[deep]=;
if(deep<K)
for(edges *i=head[x];i;i=i->last) if(i->v!=fa&&vis[i->v]==){
update(i->v,x,w+i->w,deep+);
}
}
inline void solve(int x){
clocks++;
top=0x7fffffff;
dfs(x,x);
vis[root]=true;
x=root;
int num();
T[]=clocks;
for(edges *i=head[x];i;i=i->last)if(vis[i->v]^){
sons[++num]=(node){i->v,i->w};
}
sort(sons+,sons++num);
for(int i=;i<=num;i++){
calc(sons[i].v,x,sons[i].w,);
if(i<num)
update(sons[i].v,x,sons[i].w,);
}
for(edges *i=head[x];i;i=i->last) if(vis[i->v]^)
if(size[i->v]>=K){
tot=size[i->v],solve(i->v);
}
}
int main(){
n=read(),m=read(),K=read();
for(int i=,u,v,w;i<=m;i++){
u=read(),v=read(),w=read();
push(u,v,w);push(v,u,w);
}
spfa();
memset(vis,,sizeof(vis));
memset(head,,sizeof(head));
cnt=;
for(int i=;i<=n;i++)
push(from[i],i,dis[i]-dis[from[i]]),
push(i,from[i],dis[i]-dis[from[i]]);
tot=n;
cnts[]=;
solve();
printf("%d %d\n",ans,sum);
}
【BZOJ 4016】 [FJOI2014]最短路径树问题的更多相关文章
- bzoj 4016 [FJOI2014]最短路径树问题(最短路径树+树分治)
4016: [FJOI2014]最短路径树问题 Time Limit: 5 Sec Memory Limit: 512 MBSubmit: 426 Solved: 147[Submit][Stat ...
- bzoj 4016: [FJOI2014]最短路径树问题
bzoj4016 最短路路径问题 Time Limit: 5 Sec Memory Limit: 512 MB Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点 ...
- BZOJ 4016: [FJOI2014]最短路径树问题( 最短路 + 点分治 )
先跑出最短路的图, 然后对于每个点按照序号从小到大访问孩子, 就可以搞出符合题目的树了. 然后就是经典的点分治做法了. 时间复杂度O(M log N + N log N) -------------- ...
- BZOJ 4016 [FJOI2014]最短路径树问题 (贪心+点分治)
题目大意:略 传送门 硬是把两个题拼到了一起= = $dijkstra$搜出单源最短路,然后$dfs$建树,如果$dis_{v}=dis_{u}+e.val$,说明这条边在最短路图内,然后像$NOIP ...
- [BZOJ4016][FJOI2014]最短路径树问题(dijkstra+点分治)
4016: [FJOI2014]最短路径树问题 Time Limit: 5 Sec Memory Limit: 512 MBSubmit: 1796 Solved: 625[Submit][Sta ...
- 【BZOJ4016】[FJOI2014]最短路径树问题
[BZOJ4016][FJOI2014]最短路径树问题 题面 bzoj 洛谷 题解 虽然调了蛮久,但是思路还是蛮简单的2333 把最短路径树构出来,然后点分治就好啦 ps:如果树构萎了,这组数据可以卡 ...
- 【BZOJ4016】[FJOI2014]最短路径树问题(点分治,最短路)
[BZOJ4016][FJOI2014]最短路径树问题(点分治,最短路) 题面 BZOJ 洛谷 题解 首先把最短路径树给构建出来,然后直接点分治就行了. 这个东西似乎也可以长链剖分,然而没有必要. # ...
- [BZOJ4016][FJOI2014]最短路径树问题
[BZOJ4016][FJOI2014]最短路径树问题 试题描述 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径走.若有多条长 ...
- BZOJ_4016_[FJOI2014]最短路径树问题_最短路+点分治
BZOJ_4016_[FJOI2014]最短路径树问题_最短路+点分治 Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择 ...
- [FJOI2014]最短路径树问题 长链剖分
[FJOI2014]最短路径树问题 LG传送门 B站传送门 长链剖分练手好题. 如果你还不会长链剖分的基本操作,可以看看我的总结. 这题本来出的很没水平,就是dijkstra(反正我是不用SPFA)的 ...
随机推荐
- MySQL 表名区分大小写设置
1.关闭MySQL服务: 控制面板主页-管理工具-服务-MySQL服务 2.在服务器运行目录找到my.ini 或者my.cnf文件: 在[mysqld]下面增加一行添加 :lower_ ...
- 使用XStream是实现XML与Java对象的转换(1)--简介及入门示例
一.简单介绍 XStream是thoughtworks开发的开源框架,用于实现XML数据于Java对象.Json数据的转换.它不需要schema或其他的mapping文件就可以进行java对象和xml ...
- c#实例化继承类,必须对被继承类的程序集做引用
0x00 问题 类型“Model.NewModel”在未被引用的程序集中定义.必须添加对程序集“Model, Version=1.0.0.0, Culture=neutral, PublicKeyTo ...
- html5中新增的属性和删除的属性
一.表单新增的属性 1.对input(type="text").select.textarea与button元素指定autofocus属性,它以指定属性的方式让元素在画面打开时自动 ...
- Spring的事务 之 9.1 数据库事务概述 ——跟我学spring3
9.1 数据库事务概述 事务首先是一系列操作组成的工作单元,该工作单元内的操作是不可分割的,即要么所有操作都做,要么所有操作都不做,这就是事务. 事务必需满足ACID(原子性.一致性.隔离性和持久性 ...
- Javascript、CSS、HTML面试题
1 JS中的三种弹出式消息提醒(警告窗口.确认窗口.信息输入窗口)的命令是什么? alert confirm prompt 2声明一个已经存在一个CSS有几种方式? 1.导入一个已经存 ...
- 运行Applet程序
[操作方法1:]① 编辑源程序welcome.java.② 编译程序 javac welcome.java③ 将Applet嵌入HTML网页.方法是,用记事本创建一个文件,文件内容如下:<app ...
- quicksort(java版)
相信大家都知道几种排序算法,比如说冒泡排序,选择排序,插入排序等等,这些个算法都不是很难,自己多多理解理解就能掌握了,而今天我们要谈的就是重头戏就是快速排序. 引用大牛的思想来对排序算法解释一下.(文 ...
- 子RelativeLayout与layout_alignParentBottom属性会撑大视图
如title所示,在一个子RelativeLayout中的某个元素如果设置了layout_alignParentBottom属性会导致这个RelativeLaytou的height wrap_cont ...
- Android设计开发笔记
1.因为Android的开发是基于框架的开发:往对方指定的位置加代码:其运行的Message\Handler机制也决定了其单步跟踪也不方便,所以建立新代码时要多Log,这样不但便于调试,而且帮助你加深 ...