BZOJ 4016 最短路径树问题 最短路径树构造+点分治
题目:
分析:
大家都说这是一道强行拼出来的题,属于是两种算法的模板题。
我们用dijkstra算法算出1为源点的最短路数组,然后遍历一下建出最短路树。
之后就是裸的点分治算法,一个桶,两个变量就解决了这道题。
代码:
#include<bits/stdc++.h>
#define pi pair<int,int>
#define pq priority_queue
#define mp(a,b) make_pair(a,b)
#define ms(a,x) memset(a,x,sizeof(a))
using namespace std;
const int N=;
vector< pi >g[N];
struct node{int y,z,nxt;}e[N*];
int n,m,k,h[N],c=,dis[N],vis[N],nm[N];
int ans2,md,rt,sm,siz[N],s[N],ans,f[N];
pq< pi,vector< pi >,greater< pi > >q;
void add(int x,int y,int z){
e[++c]=(node){y,z,h[x]};h[x]=c;
e[++c]=(node){x,z,h[y]};h[y]=c;
} void dij(){
ms(vis,);ms(dis,0x3f);
dis[]=;q.push(mp(,));
while(!q.empty()){
int x=q.top().second;q.pop();
if(vis[x]) continue;vis[x]=;
for(int i=;i<g[x].size();i++){
int y=g[x][i].first,
d=g[x][i].second;
if(dis[y]>dis[x]+d) dis[y]=dis[x]+d,
q.push(mp(dis[y],y));
}
} return ;
} void rebuild(int x){
vis[x]=;
for(int i=;i<g[x].size();i++){
int y=g[x][i].first,d=g[x][i].second;
if(vis[y]||dis[x]+d!=dis[y]) continue;
add(x,y,d);rebuild(y);
} return ;
} void getrt(int x,int fa){
siz[x]=;f[x]=;
for(int i=h[x],y;i;i=e[i].nxt)
if(!vis[y=e[i].y]&&y!=fa) getrt(y,x),
siz[x]+=siz[y],f[x]=max(f[x],siz[y]);
f[x]=max(f[x],sm-siz[x]);
if(f[rt]>f[x]) rt=x;return ;
} void dfs(int x,int fa,int nw){
md=max(md,nw);
if(nw==k-){
if(ans==dis[x]) ans2++;
if(dis[x]>ans) ans2=,
ans=dis[x];return ;
} int nans=-;
if(s[k--nw]!=-) nans=dis[x]+s[k--nw];
if(ans==nans) ans2+=nm[k--nw];
if(nans>ans) ans2=nm[k--nw],ans=nans;
for(int i=h[x],y;i;i=e[i].nxt)
if(!vis[y=e[i].y]&&y!=fa)
dis[y]=dis[x]+e[i].z,dfs(y,x,nw+);
} void update(int x,int fa,int nw){
if(nw==k-) return ;
if(s[nw]==dis[x]) nm[nw]++;
else s[nw]=max(s[nw],dis[x]),nm[nw]=;
for(int i=h[x],y;i;i=e[i].nxt)
if(!vis[y=e[i].y]&&y!=fa) update(y,x,nw+);
} void solve(int x){
md=;vis[x]=;
for(int i=h[x],y;i;i=e[i].nxt)
if(!vis[y=e[i].y]) dis[y]=e[i].z,
dfs(y,x,),update(y,x,);
for(int i=;i<=md;i++) s[i]=-,nm[i]=;
for(int i=h[x],y;i;i=e[i].nxt)
if(!vis[y=e[i].y]) sm=siz[y],rt=,
getrt(y,x),solve(rt);
} int main(){
f[]=0x3f3f3f3f;scanf("%d%d%d",&n,&m,&k);
for(int i=,x,y,z;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
g[x].push_back(mp(y,z));
g[y].push_back(mp(x,z));
} for(int i=;i<=n;i++)
sort(g[i].begin(),g[i].end());
dij();ms(vis,);rebuild();
sm=n;rt=;ms(vis,);
ms(dis,);ms(s,-);
getrt(,);solve(rt);
printf("%d %d\n",ans,ans2);
return ;
}
最短路树+点分治
BZOJ 4016 最短路径树问题 最短路径树构造+点分治的更多相关文章
- “中兴捧月”比赛之——二叉查找树(BST)树的最短路径Java求解
问题描述: BST树,又称二叉查找树,求其到所有叶子节点路径的最小值 测试用例一: 10 5 20 返回15: 测试用例二: 100 20 70 110 120 10 null null 89 nu ...
- BZOJ_4016_[FJOI2014]最短路径树问题_最短路+点分治
BZOJ_4016_[FJOI2014]最短路径树问题_最短路+点分治 Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择 ...
- bzoj 3611: [Heoi2014]大工程 虚树
题目: 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通道需要的代价为树上 ...
- [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】
题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...
- BZOJ.4553.[HEOI2016&TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)
题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j) if(a[ ...
- BZOJ.1901.Dynamic Rankings(树状数组套主席树(动态主席树))
题目链接 BZOJ 洛谷 区间第k小,我们可以想到主席树.然而这是静态的,怎么支持修改? 静态的主席树是利用前缀和+差分来求解的,那么对于每个位置上的每棵树看做一个点,拿树状数组更新. 还是树状数组的 ...
- dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448
4448: [Scoi2015]情报传递 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 588 Solved: 308[Submit][Status ...
- 【BZOJ】4129: Haruna’s Breakfast 树分块+带修改莫队算法
[题意]给定n个节点的树,每个节点有一个数字ai,m次操作:修改一个节点的数字,或询问一条树链的数字集合的mex值.n,m<=5*10^4,0<=ai<=10^9. [算法]树分块+ ...
- BZOJ 3672 [NOI2014]购票 (凸优化+树剖/树分治)
题目大意: 略 题面传送门 怎么看也是一道$duliu$题= = 先推式子,设$dp[x]$表示到达$x$点到达1节点的最小花费 设$y$是$x$的一个祖先,则$dp[x]=min(dp[y]+(di ...
- [BZOJ 2989]数列(二进制分组+主席树)
[BZOJ 2989]数列(二进制分组+主席树) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[ ...
随机推荐
- netty与MQ使用心得
最近在做分布式的系统,使用netty与mq进行远程RPC调用,现将心得经验总结一下. 我们公司的服务器在云端机房,在每一个店面有一个服务器,店面服务器外网无法访问. 我们的做法是店面服务器在启动时与云 ...
- HDU-2182-Frog
链接:https://vjudge.net/problem/HDU-2182 题意: 有一只青蛙,有n个节点,开始时在1节点,有k次往右跳的机会,每次跳的距离是a-b之间. 每个节点有一个值,到达那个 ...
- 通过API获取统计信息时报Access denied错误处理记录
通过API获取HDFS统计信息时报Access denied错误信息,错误信息如下: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.s ...
- JS中对数组元素进行增删改移
在js中对数组元素进行增删改移,简单总结了一下方法: 方法 说明 实例 push( ); 在原来数组中的元素最后面添加元素 arr.push("再见58"); unshift( ) ...
- Java中的数据类型——通过示例学习Java编程(5)
作者:CHAITANYA SINGH 来源:https://www.koofun.com//pro/kfpostsdetail?kfpostsid=15 数据类型用来定义变量可以采用的值,例如,如果变 ...
- 2017 清北学堂 Day 6终极考试报告
预计分数: 100+70+70 = 240 实际假分数 : 40+80+70= 190 in cena(好吧不得不承认这个分数,,,,,,=.=) 实际真分数 : 100+80+100 = 280 ...
- IT之家学院:使用CMD命令行满速下载百度云
转自:https://www.toutiao.com/a6545305189685920259/?tt_from=android_share&utm_campaign=client_share ...
- 更改IDEA默认使用JDK1.5编译项目
在使用IDEA编译项目时,总是提示我编译失败,有些功能是在1.5之后的版本才支持.废了好大的功夫才编译成功.下面呢,就是更改编译的过程了! 一.初步更改 使用快捷键Ctrl+Alt+Shift+S打开 ...
- EJB2.0教程 详解EJB技术及实现原理
EJB是什么呢?EJB是一个J2EE体系中的组件.再简单的说它是一个能够远程调用的javaBean.它同普通的javaBean有两点不同.第一点,就是远程调用.第二点,就是事务的功能,我们在EJB中声 ...
- python打开文件可以有多种模式
一.python打开文件可以有多种模式,读模式.写模式.追加模式,同时读写的模式等等,这里主要介绍同时进行读写的模式r+ python通过open方法打开文件 file_handler = open( ...