[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. ...
随机推荐
- R语言中的聚类的使用
这里的聚类主要用到K-Means和K-Medoide聚类.在进行聚类之前,为了避免不同参数之间量纲不同所造成的影响,先将数据进行(0-1)标准化 # 如参数weight data$weight < ...
- 20165330 2017-2018-2 《Java程序设计》第5周学习总结
课本知识总结 第七章 内部类与异常类 内部类:类的一种成员 外嵌类:包含内部类的类称为内部类的外嵌类 二者关系: 内部类的外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外嵌类中的方法. ...
- textarea文本输入区内实现换行
在文本间输入 即可成功换行 <textarea class="mytextarea">1.第一行 2.第二行 </textarea>
- Notice: Undefined index: wjs_cookie
w执行顺序. ok <!doctype html> <html> <head> <meta charset="UTF-8"> < ...
- remote tomcat monitor---jmc--jvisualvm
http://mspring.org/article/1229----------jmc http://doorgods.blog.163.com/blog/static/78547857201481 ...
- 小程序 wx.navigateTo传值总结
wx.navigateTo(Object object) 保留当前页面,跳转到应用内的某个页面.但是不能跳到 tabbar 页面.使用 wx.navigateBack 可以返回到原页面.小程序中页面栈 ...
- Linux IPC之管道通信
2017-04-07 管道通信在linux中使用较为频繁的进程通信机制.基于unix一切皆文件的传统,管道也是一种文件.所以可以使用一般的VFS接口对管道进行读写操作,如read.write.具体管道 ...
- mysql表的完整性约束
概览 为了防止不符合规范的数据进入数据库,在用户对数据进行插入.修改.删除等操作时,DBMS自动按照一定的约束条件对数据进行监测, 使不符合规范的数据不能进入数据库,以确保数据库中存储的数据正确.有效 ...
- JS片段大总结
html中的标签都可以加一个id的属性. <body> <div id="tree" data-leaves="47" data-plant- ...
- [笔记]Python中模块互相调用的例子
python中模块互相调用容易出错,经常是在本地路径下工作正常,切换到其他路径来调用,就各种模块找不到了. 解决方法是通过__file__定位当前文件的真实路径,再通过sys.path.append( ...