[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. ...
随机推荐
- HDU3535——AreYouBusy
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3535 题目意思:给出两个数n,T,分别表示有n个任务集合,T的总时间,对于每个任务集合有两个属性m和t ...
- django高级应用(分页功能)
django高级应用(分页功能) 1.原生分页应用 前端html代码 <!DOCTYPE html> <html lang="en"> <head&g ...
- Java8 新特性之Lambda表达式
1. Lambda 表达式概述 Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递); Lambda 表达式可以写出更简洁,更灵活的代码 ...
- 爬虫之FileCookieJar
简介 虽然CookieJar模块能够做到给请求设置cookie,但是它的cookie是保存在内存里的,每次用都需要重新设置, 这就衍生了一个它的子类---FileCookieJar,它可以将cooki ...
- Spark高速入门指南(Quick Start Spark)
版权声明:本博客已经不再更新.请移步到Hadoop技术博客:https://www.iteblog.com https://blog.csdn.net/w397090770/article/detai ...
- 如何制作一款HTML5 RPG游戏引擎——第二篇,烟雨+飞雪效果
今天我们来实现烟雨+飞雪效果.首先来说,一款经典的RPG游戏难免需要加入天气的变化.那么为了使我们的RPG游戏引擎更完美,我们就只好慢慢地实现它. 本文为该系列文章的第二篇,如果想了解以前的文章可以看 ...
- 简单的SQL注入学习
引贴: http://blog.163.com/lucia_gagaga/blog/static/26476801920168184648754/ 首先需要编写一个php页面,讲php页面放入/opt ...
- Elment UI的使用说明
一. Elment UI 1. 简介 Element UI是饿了么团队提供的一套基于Vue2.0的组件库,可以快速搭建网站,提高开发效率,就如同bootstrap. 2.组件分类 ElementUI ...
- Mediakit报告设备商的空间不足以执行此操作的纯MAC解法
使用Mac对磁盘进行分区,显示“Mediakit报告设备商的空间不足以执行此操作”,该怎么办? What 买了一个4TB的移动硬盘,准备进行分区给Time Machine用. 硬盘自带是HDFS的,所 ...
- 支持向量机SVM、优化问题、核函数
1.介绍 它是一种二类分类模型,其基本模型定义为特征空间上的间隔最大的线性分类器,即支持向量机的学习策略便是间隔最大化,最终可转化为一个凸二次规划问题的求解. 2.求解过程 1.数据分类—SVM引入 ...