[BZOJ4016][FJOI2014]最短路径树问题
[BZOJ4016][FJOI2014]最短路径树问题
试题描述
输入
第一行输入三个正整数n,m,K,表示有n个点m条边,要求的路径需要经过K个点。接下来输入m行,每行三个正整数Ai,Bi,Ci(1<=Ai,Bi<=n,1<=Ci<=10000),表示Ai和Bi间有一条长度为Ci的边。数据保证输入的是连通的无向图。
输出
输出一行两个整数,以一个空格隔开,第一个整数表示包含K个点的路径最长为多长,第二个整数表示这样的不同的最长路径有多少条。
输入示例
输出示例
数据规模及约定
对于所有数据n<=30000,m<=60000,2<=K<=n。数据保证最短路径树上至少存在一条长度为K的路径。
题解
对于每一个点的出边按照目标点编号从小到大排序,跑一边 Dijkstra,构造出树,再套点分治。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 30010
#define maxm 60010
#define oo 2147483647
int n, m, M, K;
struct Edge {
int v, w;
Edge() {}
Edge(int _, int __): v(_), w(__) {}
bool operator < (const Edge& t) const { return v < t.v; }
} ;
vector <Edge> E[maxn]; bool vis[maxn];
int d[maxn], fa[maxn], fad[maxn];
struct Node {
int u, d;
Node() {}
Node(int _, int __): u(_), d(__) {}
bool operator < (const Node& t) const { return d > t.d; }
} ;
priority_queue <Node> Q;
void Dijkstra() {
for(int i = 1; i <= n; i++) d[i] = oo;
d[1] = 0;
Q.push(Node(1, 0));
while(!Q.empty()) {
int u = Q.top().u; Q.pop();
if(vis[u]) continue;
vis[u] = 1;
for(int i = 0; i < E[u].size(); i++)
if(d[E[u][i].v] > d[u] + E[u][i].w) {
d[E[u][i].v] = d[u] + E[u][i].w;
fa[E[u][i].v] = u; fad[E[u][i].v] = E[u][i].w;
if(!vis[E[u][i].v]) Q.push(Node(E[u][i].v, d[E[u][i].v]));
}
}
return ;
} int head[maxn], to[maxm], next[maxm], dist[maxm];
void AddEdge(int a, int b, int c) {
to[++m] = b; dist[m] = c; next[m] = head[a]; head[a] = m;
swap(a, b);
to[++m] = b; dist[m] = c; next[m] = head[a]; head[a] = m;
return ;
} int root, size, siz[maxn], f[maxn], ans, ansc;
void getroot(int u, int pa) {
siz[u] = 1; f[u] = 0;
for(int e = head[u]; e; e = next[e]) if(!vis[to[e]] && to[e] != pa) {
getroot(to[e], u);
siz[u] += siz[to[e]];
f[u] = max(f[u], siz[to[e]]);
}
f[u] = max(f[u], size - siz[u]);
if(f[u] < f[root]) root = u;
return ;
}
int A[maxn], Ac[maxn], B[maxn], Bc[maxn], mxd;
void dfs(int u, int d, int dep, int pa) {
mxd = max(mxd, dep);
// printf("XXX: %d %d %d\n", u, d, dep);
if(!Ac[dep] || A[dep] < d) A[dep] = d, Ac[dep] = 1;
else if(A[dep] == d) Ac[dep]++;
for(int e = head[u]; e; e = next[e]) if(!vis[to[e]] && to[e] != pa)
dfs(to[e], d + dist[e], dep + 1, u);
return ;
}
void solve(int u) {
// printf("u: %d\n", u);
vis[u] = 1;
int Mxd = 0;
for(int e = head[u]; e; e = next[e]) if(!vis[to[e]]) {
mxd = 0;
dfs(to[e], dist[e], 1, u);
Mxd = max(Mxd, mxd);
Ac[0] = Bc[0] = 1;
// for(int i = 1; i <= mxd; i++) printf("here: %d(%d) ", A[i], Ac[i]); putchar('\n');
for(int i = 1; i <= min(K, mxd); i++)
if(!ansc || ans < A[i] + B[K-i]) ans = A[i] + B[K-i], ansc = Ac[i] * Bc[K-i];
else if(ans == A[i] + B[K-i]) ansc += Ac[i] * Bc[K-i];
for(int i = 1; i <= mxd; i++) {
if(!Bc[i] || B[i] < A[i]) B[i] = A[i], Bc[i] = Ac[i];
else if(B[i] == A[i]) Bc[i] += Ac[i];
A[i] = Ac[i] = 0;
}
}
for(int i = 1; i <= Mxd; i++) B[i] = Bc[i] = 0;
for(int e = head[u]; e; e = next[e]) if(!vis[to[e]]) {
root = 0; f[0] = n + 1; size = siz[u]; getroot(to[e], u);
solve(root);
}
return ;
} int main() {
n = read(); M = read(); K = read() - 1;
for(int i = 1; i <= M; i++) {
int a = read(), b = read(), c = read();
E[a].push_back(Edge(b, c)); E[b].push_back(Edge(a, c));
}
for(int i = 1; i <= n; i++) sort(E[i].begin(), E[i].end()); Dijkstra();
for(int i = 2; i <= n; i++) AddEdge(i, fa[i], fad[i]);
// for(int i = 1; i <= n; i++) printf("%d ", fa[i]); putchar('\n');
memset(vis, 0, sizeof(vis));
root = 0; f[0] = n + 1; size = n; getroot(1, 0);
solve(root); printf("%d %d\n", ans, ansc); return 0;
}
简直是强行乱套
[BZOJ4016][FJOI2014]最短路径树问题的更多相关文章
- [BZOJ4016][FJOI2014]最短路径树问题(dijkstra+点分治)
4016: [FJOI2014]最短路径树问题 Time Limit: 5 Sec Memory Limit: 512 MBSubmit: 1796 Solved: 625[Submit][Sta ...
- 【BZOJ4016】[FJOI2014]最短路径树问题
[BZOJ4016][FJOI2014]最短路径树问题 题面 bzoj 洛谷 题解 虽然调了蛮久,但是思路还是蛮简单的2333 把最短路径树构出来,然后点分治就好啦 ps:如果树构萎了,这组数据可以卡 ...
- 【BZOJ4016】[FJOI2014]最短路径树问题 最短路径树+点分治
[BZOJ4016][FJOI2014]最短路径树问题 Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径 ...
- 【BZOJ4016】[FJOI2014]最短路径树问题(点分治,最短路)
[BZOJ4016][FJOI2014]最短路径树问题(点分治,最短路) 题面 BZOJ 洛谷 题解 首先把最短路径树给构建出来,然后直接点分治就行了. 这个东西似乎也可以长链剖分,然而没有必要. # ...
- bzoj 4016 [FJOI2014]最短路径树问题(最短路径树+树分治)
4016: [FJOI2014]最短路径树问题 Time Limit: 5 Sec Memory Limit: 512 MBSubmit: 426 Solved: 147[Submit][Stat ...
- BZOJ_4016_[FJOI2014]最短路径树问题_最短路+点分治
BZOJ_4016_[FJOI2014]最短路径树问题_最短路+点分治 Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择 ...
- 【BZOJ-4016】最短路径树问题 Dijkstra + 点分治
4016: [FJOI2014]最短路径树问题 Time Limit: 5 Sec Memory Limit: 512 MBSubmit: 1092 Solved: 383[Submit][Sta ...
- [FJOI2014]最短路径树问题 长链剖分
[FJOI2014]最短路径树问题 LG传送门 B站传送门 长链剖分练手好题. 如果你还不会长链剖分的基本操作,可以看看我的总结. 这题本来出的很没水平,就是dijkstra(反正我是不用SPFA)的 ...
- 洛谷 [FJOI2014]最短路径树问题 解题报告
[FJOI2014]最短路径树问题 题目描述 给一个包含\(n\)个点,\(m\)条边的无向连通图.从顶点\(1\)出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径走.若有多 ...
随机推荐
- 未签名有元程序集 Unsigned Friend Assemblies
C#中的访问修饰符internal可以使类型在同程序集中可以被相互访问.但有时会有这样一个要求,我们希望一个程序集中的类型可以被外部的某些程序集访问,如果设置成public的话,就被所有的外部程序集访 ...
- matlab注释
单行注释: 两个'%': 多行注释: A. %{ 若干语句 %} B. 注释: 选中要注释的若干语句, 编辑器菜单Text->Comment, 或者快捷键Ctrl+R 取消注释: 选中要取消注释 ...
- VS2012 error C2664: “std::make_pair”:无法将左值绑定到右值引用
在vs2012(c++)make_pair()改动: C++: template <class T1, class T2> pair<V1, V2> make_pair(T1& ...
- Linux常用服务部署与优化之NFS篇
NFS(network file system)的简称,是linux系统之间常用的一种文件共享方式,下面简述其搭建过程,需要两个linux系统的虚拟机,假设客户端的ip为192.168.1.105,服 ...
- HTML学习笔记——CSS初涉
1>嵌入式css写法 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http ...
- 个人js
1.网页右侧地图浮动楼层,超过100px就显示 $(window).scroll(function(){ ){ //距顶部多少像素时,出现返回顶部按钮 $("#floor").fa ...
- Elmah 日志记录组件
http://www.cnblogs.com/jys509/p/4571298.html 简介 ELMAH(Error Logging Modules and Handlers)错误日志记录模块和处理 ...
- jQuery监听键盘事件及相关操作使用教程
一.首先需要知道的是: 1.keydown() keydown事件会在键盘按下时触发. 2.keyup() keyup事件会在按键释放时触发,也就是你按下键盘起来后的事件 3.keypress() k ...
- 工具,如何去掉百度编辑器 ueditor 元素路径、字数统计等
去掉如下截图: 在百度编辑器 ueditor 根目录下: ueditor.config.js 文件中 搜索并将参数elementPathEnabled设置成false即可 常用功能开关如下: ,ele ...
- Effective Objective-C 2.0 — 第二章 对象、消息、运行期 - 第六条:理解“属性”这一概念
开发者通过对象来 存储并传递数据. 在对象之间传递数据并执行任务的过程就叫做“消息传递”. 这两条特性的工作原理? Objective-C运行期环境(Objective-C runtime) ,提供了 ...