bzoj4016 最短路路径问题

Time Limit: 5 Sec Memory Limit: 512 MB

Description

给一个包含n个点,m条边的无向连通图。从顶点1出发,往其余所有点分别走一次并返回。

往某一个点走时,选择总长度最短的路径走。若有多条长度最短的路径,则选择经过的顶点序列字典序最小的那条路径(如路径A为1,32,11,路径B为1,3,2,11,路径B字典序较小。注意是序列的字典序的最小,而非路径中节点编号相连的字符串字典序最小)。到达该点后按原路返回,然后往其他点走,直到所有点都走过。

可以知道,经过的边会构成一棵最短路径树。请问,在这棵最短路径树上,最长的包含K个点的简单路径长度为多长?长度为该最长长度的不同路径有多少条?

这里的简单路径是指:对于一个点最多只经过一次的路径。不同路径是指路径两端端点至少有一个不同,点A到点B的路径和点B到点A视为同一条路径。

Input

第一行输入三个正整数n,m,K,表示有n个点m条边,要求的路径需要经过K个点。

接下来输入m行,每行三个正整数\(A_i,B_i,C_i(1 \le A_i,B_i \le n,1 \le C_i \le 10000)\),表示\(A_i\)和\(B_i\)间有一条长度为\(C_i\)的边。数据保证输入的是连通的无向图。

Output

输出一行两个整数,以一个空格隔开,第一个整数表示包含K个点的路径最长为多长,第二个整数表示这样的不同的最长路径有多少条。

Sample Input

6 6 4

1 2 1

2 3 1

3 4 1

2 5 1

3 6 1

5 6 1

Sample Output

3 4

HINT

对于所有数据\(n \le 30000,m \le 60000,2 \le K \le n\)。数据保证最短路径树上至少存在一条长度为K的路径。

题解

这题很显然是一道点分治的裸题。

我们可以定义\(g[i]\)表示对于当前\(root\),深度为\(i\)的最大距离以及此距离方案数。

为了求出\(ans\),我们再用\(f[i]\)累积之前的\(g[i]\),这样,我们就可以直接点分治求出答案。

#include <vector>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int N = 30010;
typedef pair<int, int>pii;
vector<pii> G[N];
int n, m, mv, cnt, root, Siz, K;
int s[N], froot, f[2][N], g[2][N];
bool vis[N];
int to[N << 1], nxt[N << 1], head[N], W[N << 1], totE; #define Adde(a,b,c) (to[totE] = b, nxt[totE] = head[a], W[totE] = c, head[a] = totE++) //dijkstra
priority_queue<pii, vector<pii>, greater<pii> >heap;
int d[N]; void dijkstra() {
memset(d, 127, sizeof d);
heap.push(make_pair(d[1] = 0, 1));
int p, dis, w, v;
while (!heap.empty()) {
dis = heap.top().first, p = heap.top().second;
heap.pop(); if (d[p] ^ dis) continue;
sort(G[p].begin(), G[p].end());
for (int i = 0; i < G[p].size(); ++i)
if (d[v = G[p][i].first] > dis + (w = G[p][i].second)) heap.push(make_pair(d[v] = dis + w, v));
}
} void Build(int u) {
int v; vis[u] = true;
for (int i = 0; i < G[u].size(); ++i)
if (!vis[v = G[u][i].first] && d[v] == d[u] + G[u][i].second) {
Adde(v, u, G[u][i].second); Adde(u, v, G[u][i].second); Build(v);
}
} void getroot(int u, int fa) {
s[u] = 1; int mx = 0, v;
for (int it = head[u]; ~it; it = nxt[it])
if (!vis[v = to[it]] && (v ^ fa)) {
getroot(v, u); s[u] += s[v];
if (s[v] > mx) mx = s[v];
}
if (Siz - mx > mx) mx = Siz - mx;
if (froot > mx) root = u, froot = mx;
} void dfs(int u, int fa, int dep) {
if (dep > K) return; int v;
if (d[u] > g[0][dep]) g[0][dep] = d[u], g[1][dep] = 0;
if (d[u] >= g[0][dep]) ++g[1][dep];
for (int i = head[u]; ~i; i = nxt[i])
if (!vis[v = to[i]] && (v ^ fa)) {
d[v] = d[u] + W[i]; dfs(v, u, dep + 1);
}
} void solve(int u, int S) {
vis[u] = true; f[0][0] = 0; f[1][0] = 1;
int v;
for (int i = head[u]; ~i; i = nxt[i])
if (!vis[v = to[i]]) {
d[v] = W[i]; dfs(v, u, 1);
for (int j = 1; j <= K; ++j) {
if (g[0][j] + f[0][K - j] > mv) mv = g[0][j] + f[0][K - j], cnt = 0;
if (g[0][j] + f[0][K - j] >= mv) cnt += g[1][j] * f[1][K - j];
}
for (int j = 1; j <= K; ++j) {
if (g[0][j] > f[0][j]) f[0][j] = g[0][j], f[1][j] = 0;
if (g[0][j] >= f[0][j]) f[1][j] += g[1][j];
g[0][j] = g[1][j] = 0;
}
}
for (int i = 0; i <= K; ++i) f[0][i] = f[1][i] = 0;
for (int i = head[u]; ~i; i = nxt[i])
if (!vis[v = to[i]]) {
froot = Siz = s[v]; root = 0;
getroot(v, u);
solve(root, s[v]);
}
} int main() {
scanf("%d%d%d", &n, &m, &K);
--K;
int a, b, c;
while (m--) {
scanf("%d%d%d", &a, &b, &c);
G[a].push_back(make_pair(b, c));
G[b].push_back(make_pair(a, c));
}
dijkstra();
memset(head, -1, sizeof head);
Build(1);
memset(vis, 0, sizeof vis);
froot = Siz = n;
getroot(1, root = 0);
solve(root, n);
printf("%d %d\n", mv, cnt);
return 0;
}

bzoj 4016: [FJOI2014]最短路径树问题的更多相关文章

  1. bzoj 4016 [FJOI2014]最短路径树问题(最短路径树+树分治)

    4016: [FJOI2014]最短路径树问题 Time Limit: 5 Sec  Memory Limit: 512 MBSubmit: 426  Solved: 147[Submit][Stat ...

  2. BZOJ 4016: [FJOI2014]最短路径树问题( 最短路 + 点分治 )

    先跑出最短路的图, 然后对于每个点按照序号从小到大访问孩子, 就可以搞出符合题目的树了. 然后就是经典的点分治做法了. 时间复杂度O(M log N + N log N) -------------- ...

  3. BZOJ 4016 [FJOI2014]最短路径树问题 (贪心+点分治)

    题目大意:略 传送门 硬是把两个题拼到了一起= = $dijkstra$搜出单源最短路,然后$dfs$建树,如果$dis_{v}=dis_{u}+e.val$,说明这条边在最短路图内,然后像$NOIP ...

  4. [BZOJ4016][FJOI2014]最短路径树问题(dijkstra+点分治)

    4016: [FJOI2014]最短路径树问题 Time Limit: 5 Sec  Memory Limit: 512 MBSubmit: 1796  Solved: 625[Submit][Sta ...

  5. 【BZOJ4016】[FJOI2014]最短路径树问题

    [BZOJ4016][FJOI2014]最短路径树问题 题面 bzoj 洛谷 题解 虽然调了蛮久,但是思路还是蛮简单的2333 把最短路径树构出来,然后点分治就好啦 ps:如果树构萎了,这组数据可以卡 ...

  6. 【BZOJ4016】[FJOI2014]最短路径树问题(点分治,最短路)

    [BZOJ4016][FJOI2014]最短路径树问题(点分治,最短路) 题面 BZOJ 洛谷 题解 首先把最短路径树给构建出来,然后直接点分治就行了. 这个东西似乎也可以长链剖分,然而没有必要. # ...

  7. [BZOJ4016][FJOI2014]最短路径树问题

    [BZOJ4016][FJOI2014]最短路径树问题 试题描述 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径走.若有多条长 ...

  8. BZOJ_4016_[FJOI2014]最短路径树问题_最短路+点分治

    BZOJ_4016_[FJOI2014]最短路径树问题_最短路+点分治 Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择 ...

  9. [FJOI2014]最短路径树问题 长链剖分

    [FJOI2014]最短路径树问题 LG传送门 B站传送门 长链剖分练手好题. 如果你还不会长链剖分的基本操作,可以看看我的总结. 这题本来出的很没水平,就是dijkstra(反正我是不用SPFA)的 ...

随机推荐

  1. 蓝牙协议中的SBC编码

    一.从信息的传输说起  上图是一个典型的蓝牙耳机应用场景.手机上的音频信息经过编码以后通过蓝牙协议被蓝牙耳机接收,经过解码以后,蓝牙耳机成功获取手机上的音频信息,然后再转化为振动被人耳识别.这是一个 ...

  2. 阶段一:为View设置阴影和弹出动画(天气应用)

    “阶段一”是指我第一次系统地学习Android开发.这主要是对我的学习过程作个记录. 上一篇阶段一:通过网络请求,获得并解析JSON数据(天气应用)完成了应用的核心功能,接下来就要对它进行优化.今天我 ...

  3. Git和Code Review流程

    Code Review流程1.根据开发任务,建立git分支, 分支名称模式为feature/任务名,比如关于API相关的一项任务,建立分支feature/api.git checkout -b fea ...

  4. Oracle数据库11g各版本介绍及功能比较

    .标准版和企 业版.所有这些版本都使用相同的通用代码库构建,这意味着企业的数据库管理软件可以轻松地从规模较小的单一处理器服务器扩展到多处理器服务器集 群,而无需更改一行代码.Oracle数据库11g企 ...

  5. 搭建高可用的rabbitmq集群 + Mirror Queue + 使用C#驱动连接

    我们知道rabbitmq是一个专业的MQ产品,而且它也是一个严格遵守AMQP协议的玩意,但是要想骚,一定需要拿出高可用的东西出来,这不本篇就跟大家说 一下cluster的概念,rabbitmq是erl ...

  6. 体验Rabbitmq强大的【优先级队列】之轻松面对现实业务场景

    说到队列的话,大家一定不会陌生,但是扯到优先级队列的话,还是有一部分同学是不清楚的,可能是不知道怎么去实现吧,其实呢,,,这东西已 经烂大街了...很简单,用“堆”去实现的,在我们系统中有一个订单催付 ...

  7. properties属性文件工具类

    package xxx.business.utils; import org.apache.commons.configuration.ConfigurationException; import o ...

  8. IE8.0.6001这个版本执行JS报错

    现场: OS  winserver 2008 IE8.0.6001.18702   JS报错,不能登陆 OS  XP   IE8.0.6001.18702CO     JS报错,不能登陆 公司测试: ...

  9. 【转】[fix] Wireshark error: There are no interfaces on which a capture can be done. on Mac OS X

    I got the following error message when trying to open a network interface for capture using Wireshar ...

  10. jpa

    学习尚硅谷jpa笔记: 所依赖的jar包: 首先在META-INF下创建配置文件,persistence.xml <?xml version="1.0" encoding=& ...