【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)的 ...
随机推荐
- 配置使用dwr完成收邮件提示
DWR(Direct Web Remoting)是一个用于改善web页面与Java类交互的远程服务器端Ajax开源框架,可以帮助开发人员开发包含AJAX技术的网站.它可以允许在浏览器里的代码使用运行在 ...
- was上的应用程序部分启动的原因
最近几天为了方便联调,我把两个项目配置到was测试环境上,前几天还好好的,昨天忽然有一个项目反复安装后都呈现部分启动的状态,打开节点一看,偏偏没启动的那个节点就是我需要用的79节点. 这让我很郁闷,硬 ...
- 视频博文结合的教程:用nodejs实现简单的爬虫
教学视频地址: https://v.qq.com/x/page/b0643tut4ze.html 前言 本喵最近工作中需要使用node,并也想晋升为全栈工程师,所以开始了node学习之旅,在学习过 ...
- IBATIS的优缺点
ibatis优缺点总结 .优点 简单: 易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现. 实用: 提供了数据映射功能,提供了对底层数据访问的封装(例如ado.net),提供 ...
- 移动App开发基本技术面
1.UI布局 1.1.熟悉系统布局基本机制和使用方法 2.界面效果 2.1.熟悉系统提供的所有界面组件 2.2.熟悉各种功能界面效果的实现途径 2,3.动画等特殊UI效果的实现机制 3.网络请求 3. ...
- C#避免踩坑之如何添加paint事件
看截图: 首先,右击->属性 然后出来这个界面. 接下来,注意看这个界面的上面:鼠标悬停这个闪电符号,看到没,事件!! 那个闪电符号,点它! 然后下拉找到这个: 你要事先在代码里面添加Form1 ...
- php进阶篇
字符串调用: $name = 'eco'; echo $name; //eco //双引号会解析变量 echo "$name"; //eco //单引号不会解析变量 echo '$ ...
- java线程之创建线程类
1.extends Thread方法 class Person extends Thread { int sum1 = 50; // 含参构造器 public Person(String name) ...
- Java 核心卷学习笔记(一)
Java基程序设计结构 1.注释 三种注释方式: // 注释单行 /* 内容 */ 注释单行 /** * 内容 */
- Tomcat PermGen space的解决方案
Tomcat报告 Caused by: java.lang.OutOfMemoryError: PermGen space异常 内存溢出PermGen space的全称是Permanent Gener ...