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[ ...
随机推荐
- 记录下java的个人测试方法
IDEA,用 JUnitGenerator V2. 0 做单元测试.. 如果是 SpringBoot,测试类上面加注解 @RunWith(SpringJUnit4ClassRunner.class) ...
- web前端篇:html基础知识
目录 1.web前端: 2.HTML概述 2.1HTML介绍 2.2HTML在计算机中如何表现 3.HTML基础语法 4.练习题: 1.web前端: 什么是web? web 就是网页,是一种基于B/S ...
- java快速排序代码
public class test1 { public static int partition(int[] array,int lo,int hi){ int key=array[lo]; whil ...
- jq解析xml
注意:url路径不能用相对路径,需要加入http协议
- python 基础(六) 推导式
列表推导式 概念:提供了一种创建列表的简单快速的途径 (1) 一般形式 myList = [x for x in range(10)] #分解后 myList = [] for x in rang ...
- [ZJOI2008]无序运动Movement
Description D博士对物理有着深入的研究,经典物理.天体物理.量子物理都有着以他的名字命名的定理.最近D博士着迷于研究粒子运动的无规则性.对圣经深信不疑的他相信,上帝创造的任何事物必然是有序 ...
- 一、使用MyBatis
定义sql映射xml文件 userMapper.xml文件的内容如下: <!--头文件--> <!DOCTYPE mapper PUBLIC "-//mybatis.org ...
- vagrant教程
http://blog.smdcn.net/article/1308.html http://ninghao.net/blog/1566 如何定制一个自己的 vagrant box: https:// ...
- 事件冒泡之cancelBubble和stoppropagation的区别
事实上stoppropagation和cancelBubble的作用是一样的,都是用来阻止浏览器默认的事件冒泡行为. 不同之处在于stoppropagation属于W3C标准,试用于Firefox等浏 ...
- VC运行时库(/MD、/MT等)
VC项目属性→配置属性→C/C++→代码生成→运行时库 可以采用的方式有:多线程(/MT).多线程调试(/MTd).多线程DLL(/MD).多线程调试DLL(/MDd).单线程(/ML).单线程调试( ...