[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. ...
随机推荐
- 基于注解的形式配置Bean
基于注解的方式配置Bean:也就说我们在每个Bean的类名前面注解一下,Spring会自动帮我们扫描Bean放进IOC容器中 I基于注解的方式配置Bean(没有依赖关系的Bean)有两个步骤: 1组件 ...
- 通过TZ来设置嵌入式ARM+Linux的时区
1.在/etc/profile或者/root/.profile(/home/username/.profile) 在其中加入: TZ=UTC-08:00 export TZ hwclock -s
- HDU_5514_Frogs
Frogs Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- Tilera--100核cpu
市场对多核的需求越来越多,主要是因为单核处理能力不可能像以往那样不断地提升.从上世纪90 年代开始,整个产业遵循摩尔定律,即芯片上可容纳的晶体管数目每隔18个月便会增加一倍,性能也提升一倍.随着时间的 ...
- cross-compler toolchains--clfs
http://www.cnblogs.com/leaven/archive/2010/11/17/1879679.html
- Spring Data @Query查询注解的使用(六)
按照上一篇文章 我们知道 我们定义的方法 都要根据它的规范进行定义 不然就没法实用 这篇我们讲@Query 查询注解 我们就可以不需要遵循它的方法规则去编写 咱们讲@Query定义到方法上 ...
- zipline目录结构
下面列出了zipline主要的目录和文件结构和它的说明 ├── ci - 持续集成相关 ├── conda - 生成conda 包相关 ├── docs - 文档 │ ├── notebooks - ...
- 通过virt-manager 利用NFS创建、迁移虚拟机2
前面一篇文章介绍了利用NFS创建虚拟机的过程,本文就介绍下如何利用NFS对虚拟机进行动态迁移. 动态迁移就是把一台虚拟机在不停止其运行的情况下迁移到另一台物理机上.这看起来似乎不太可能,不过还好kvm ...
- 软件project--作图
软工学习进行了一个多月,但是真正静下心来学习也只是一周左右吧,这段时间里给自己印象最深刻的就是作图了, 机房收费系统我们是先进行的编码,后学习软件project对它来了一次回想性的文档编写. 刚開始当 ...
- linux 配置SSH网络传输数据安全方案,JDK,Tomcat和Eclipes
一.通过ssh实现安全远程访问linux系统 ssh :secure shell 加密: 1. 对称加密 (加密密钥与解密密钥相同) des .aes 2. 非对称加密(加密密钥与解密密钥不同) RS ...