[BZOJ4016]最短路径树问题
Description
Input
Output
Sample Input
1 2 1
2 3 1
3 4 1
2 5 1
3 6 1
5 6 1
Sample Output
设$f[i][0/1]$表示到当前分治重心的路径中点数为$i$的路径最大长度和方案数
然后注意细节就可以$A$掉它了
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
#define M 100010
#define inf 1e9
using namespace std;
int n,m,num,ans1,ans2,S,rt,k;
int head[M],dis[M],d[M],g[M],size[M],maxn[M],f[M][];
bool vis[M];
struct point{int to,next,dis;}e[M<<];
struct edge{int to,dis;};
struct node{int id,v;};
vector<edge>vec[M];
priority_queue<node>Q;
bool operator < (node a1,node a2) {
return a1.v>a2.v;
}
void add(int from,int to,int dis) {
e[++num].next=head[from];
e[num].to=to;
e[num].dis=dis;
head[from]=num;
}
void Dijkstra(int s) {
memset(dis,,sizeof(dis));
dis[s]=;
Q.push((node){s,});
while(!Q.empty()) {
int x=Q.top().id;Q.pop();
if(vis[x]) continue;
for(int i=;i<vec[x].size();i++) {
int to=vec[x][i].to;
if(dis[to]>dis[x]+vec[x][i].dis) {
dis[to]=dis[x]+vec[x][i].dis;
Q.push((node){to,dis[to]});
}
}
}
}
void build(int x) {
vis[x]=true;
for(int i=;i<vec[x].size();i++) {
int to=vec[x][i].to;
if(vis[to]) continue;
if(dis[x]+vec[x][i].dis==dis[to]) {
build(to);
add(x,to,vec[x][i].dis);
add(to,x,vec[x][i].dis);
}
}
}
void getroot(int x,int fa) {
size[x]=;maxn[x]=;
for(int i=head[x];i;i=e[i].next) {
int to=e[i].to;
if(to==fa||vis[to]) continue;
getroot(to,x),size[x]+=size[to];
maxn[x]=max(maxn[x],size[to]);
}
maxn[x]=max(maxn[x],S-size[x]);
if(maxn[x]<maxn[rt]) rt=x;
}
void cal(int x,int fa) {
if(d[x]>k) return;
if(ans1<g[x]+f[k-d[x]+(d[x]!=k)][]) ans1=g[x]+f[k-d[x]+(d[x]!=k)][],ans2=f[k-d[x]+(d[x]!=k)][];
else if(ans1==g[x]+f[k-d[x]+(d[x]!=k)][]) ans2+=f[k-d[x]+(d[x]!=k)][];
for(int i=head[x];i;i=e[i].next) {
int to=e[i].to;
if(to==fa||vis[to]) continue;
d[to]=d[x]+,g[to]=g[x]+e[i].dis;
cal(to,x);
}
}
void insert(int x,int fa) {
if(d[x]<=k) {
if(f[d[x]][]<g[x]) f[d[x]][]=g[x],f[d[x]][]=;
else if(f[d[x]][]==g[x]) f[d[x]][]++;
for(int i=head[x];i;i=e[i].next)
if(!vis[e[i].to]&&e[i].to!=fa)
insert(e[i].to,x);
}
}
void del(int x,int fa) {
if(d[x]<=k) {
f[d[x]][]=f[d[x]][]=-inf;
for(int i=head[x];i;i=e[i].next)
if(!vis[e[i].to]&&e[i].to!=fa)
del(e[i].to,x);
}
}
void solve(int x) {
//cout<<x<<endl;
vis[x]=true;f[][]=,f[][]=;
for(int i=head[x];i;i=e[i].next) {
int to=e[i].to;
if(vis[to]) continue;
d[to]=,g[to]=e[i].dis,cal(to,x);
insert(to,x);
}
for(int i=head[x];i;i=e[i].next)
if(!vis[e[i].to])
del(e[i].to,x);
for(int i=head[x];i;i=e[i].next) {
int to=e[i].to;
if(vis[to]) continue;
S=size[to],rt=,getroot(to,);
solve(rt);
}
}
int main() {
scanf("%d%d%d",&n,&m,&k);
memset(f,,sizeof(f));
for(int i=;i<=m;i++) {
int a,b,c;scanf("%d%d%d",&a,&b,&c);
vec[a].push_back((edge){b,c});
vec[b].push_back((edge){a,c});
}
Dijkstra(),memset(vis,,sizeof(vis)),build();
memset(vis,,sizeof(vis)),maxn[]=S=n,getroot(,);
solve(rt);printf("%d %d",ans1,ans2);
return ;
}
[BZOJ4016]最短路径树问题的更多相关文章
- BZOJ 4016 最短路径树问题 最短路径树构造+点分治
题目: BZOJ4016最短路径树问题 分析: 大家都说这是一道强行拼出来的题,属于是两种算法的模板题. 我们用dijkstra算法算出1为源点的最短路数组,然后遍历一下建出最短路树. 之后就是裸的点 ...
- [BZOJ4016][FJOI2014]最短路径树问题
[BZOJ4016][FJOI2014]最短路径树问题 试题描述 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径走.若有多条长 ...
- 【BZOJ4016】[FJOI2014]最短路径树问题
[BZOJ4016][FJOI2014]最短路径树问题 题面 bzoj 洛谷 题解 虽然调了蛮久,但是思路还是蛮简单的2333 把最短路径树构出来,然后点分治就好啦 ps:如果树构萎了,这组数据可以卡 ...
- [BZOJ4016][FJOI2014]最短路径树问题(dijkstra+点分治)
4016: [FJOI2014]最短路径树问题 Time Limit: 5 Sec Memory Limit: 512 MBSubmit: 1796 Solved: 625[Submit][Sta ...
- 【BZOJ4016】[FJOI2014]最短路径树问题 最短路径树+点分治
[BZOJ4016][FJOI2014]最短路径树问题 Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径 ...
- 【BZOJ4016】[FJOI2014]最短路径树问题(点分治,最短路)
[BZOJ4016][FJOI2014]最短路径树问题(点分治,最短路) 题面 BZOJ 洛谷 题解 首先把最短路径树给构建出来,然后直接点分治就行了. 这个东西似乎也可以长链剖分,然而没有必要. # ...
- 【BZOJ-4016】最短路径树问题 Dijkstra + 点分治
4016: [FJOI2014]最短路径树问题 Time Limit: 5 Sec Memory Limit: 512 MBSubmit: 1092 Solved: 383[Submit][Sta ...
- Bzoj4016/洛谷P2993 [FJOI2014] 最短路径树问题(最短路径问题+长链剖分/点分治)
题面 Bzoj 洛谷 题解 首先把最短路径树建出来(用\(Dijkstra\),没试过\(SPFA\)\(\leftarrow\)它死了),然后问题就变成了一个关于深度的问题,可以用长链剖分做,所以我 ...
- BZOJ4016:[FJOI2014]最短路径树问题
浅谈树分治:https://www.cnblogs.com/AKMer/p/10014803.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem. ...
随机推荐
- [iOS微博项目 - 4.1] - cell的frame模型
github: https://github.com/hellovoidworld/HVWWeibo A.cell的frame模型设计 1.需求 每个cell都有一个frame实例引用 frame模型 ...
- Python overall structer
在C/C++/Java中,main是程序执行的起点,Python中,也有类似的运行机制,但方式却截然不同:Python使用缩进对齐组织代码的执行,所有没有缩进的代码(非函数定义和类定义),都会在载入时 ...
- c++ socket相关
http://blog.sina.com.cn/s/blog_43ad62c70100gtow.html,一个简单的C语言的socket服务器和客户端程序 http://www.cnblogs.com ...
- 在HTML里面HEAD部分的META元素要表达的内容是什么
1.name属性主要有以下几种参数: A.Keywords(关键字) 说明:keywords用来告诉搜索引擎你网页的关键字是什么. 举例:<meta name ="keywords&q ...
- lowB三人组算法-冒泡排序-选择排序-插入排序
冒泡排序 时间复杂度:O(n2) 算法稳定 第一趟,从第一个数开始,相邻两个数比较,大的数交换放后,交换到最后位置得出一个第一大数 第二趟,从第一个数开始,相邻两个数比较,大的数交换放后,交换到倒数 ...
- 一个误区(关于javascript的字符串拼接)
前段时间听说了一个问题,说是,javascript中使用+=来拼接字符串会比使用Array的join方法慢几十倍以上,今天在工作间歇,就写了个例 子验证了一下,结果确完全相反,使用+=比join要快( ...
- 系统架构--分布式计算系统spark学习(三)
通过搭建和运行example,我们初步认识了spark. 大概是这么一个流程 ------------------------------ -------------- ...
- Python 装饰器的诞生过程
Python中的装饰器是通过利用了函数特性的闭包实现的,所以在讲装饰器之前,我们需要先了解函数特性,以及闭包是怎么利用了函数特性的 ① 函数特性 Python中的函数特性总的来说有以下四点: 1. ...
- 001-hive是什么
一.基本概念 官网含义:https://cwiki.apache.org/confluence/display/Hive/Home The Apache Hive™ data warehouse so ...
- spring MVC学习(二)---配置相关的东西
1.在上一节中我们提到过每一个DispatcherServlet都会有一个上下文 (WebApplictionContext),并且继承了这些上下文中的bean,其中以一些"特殊" ...