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[ ...
随机推荐
- 阿里云物联网 .NET Core 客户端 | CZGL.AliIoTClient:5. 设置设备属性
文档目录: 说明 1. 连接阿里云物联网 2. IoT 客户端 3. 订阅Topic与响应Topic 4. 设备上报属性 4.1 上报位置信息 5. 设置设备属性 6. 设备事件上报 7. 服务调用 ...
- hyperledger fabric 1.0.5 分布式部署 (六)
如何在相同的peer 节点上创建多个 channel 作者在hyperledger fabric 1.0.5 分布式部署 (五)已经向读者们介绍了一个简单的fabric 的部署流程,那么根据上一篇博客 ...
- pytest入门学习(1)
系统ubuntu 12.04 , 可上网 一.安装: 1.安装 setuptools 下载页面:https://bitbucket.org/pypa/setuptools/get/default.ta ...
- 慕课笔记-Java入门第二季
1.java对象的使用 (1)创建对象 类名 对象名=new 类名(); (2)使用对象 引用对象的属性:对象名.属性; 引用对象的方法:对象名.方法(); Note: ①Java会给成员变量赋初始值 ...
- E. XOR and Favorite Number (莫队板子题)
题目链接 #include <bits/stdc++.h> using namespace std; typedef long long ll; inline int read() { , ...
- TabBar背景颜色设置
// 第一种方式 // [[UITabBar appearance] setBarTintColor:[UIColor blackColor]]; // [UITabBar appearance].t ...
- Guard Duty (hard) Codeforces - 958E3 || uva 1411
https://codeforces.com/contest/958/problem/E3 当没有三点共线时,任意一个这样的点集都是保证可以找到答案的,(考虑任意一种有相交的连线方案,一定可以将其中两 ...
- java threadLocal的初探
在网上找了半天,终于找到一篇靠谱的文章了. 文章地址:http://qifuguang.me/2015/09/02/[Java%E5%B9%B6%E5%8F%91%E5%8C%85%E5%AD%A6% ...
- 自定义xml配置文件之dtd文件校验
用了很多第三方库,也看了些源码,总是想如果自己写一个类似的库,读取xml配置文件(properties配置文件比较简单) 该如何给配置文件添加头,添加校验,因为xml配置文件相对于properties ...
- 開玩樹莓派(二):配置IP,實現無顯示器局域網內Putty連接和RDP遠程
目錄: 開玩樹莓派(一):安裝Raspbian系統 開玩樹莓派(二):配置IP,實現無顯示器局域網內Putty連接和RDP遠程 開玩樹莓派(三):Python編程 開玩樹莓派(四):GPIO控制和遠程 ...