BZOJ 2750 HAOI 2012 Road 高速公路 最短路
题意:
给出一个有向图,求每条边有多少次作为最短路上的边(任意的起始点)。
范围:n <= 1500, m <= 5005
分析:
一个比较容易想到的思路:以每个点作为起点,做一次SPFA,记f[i]表示从点S到达点i的最短路数,g[i]表示从点i到达点T的最短路数。
那么对于任意一条边,答案就是∑f[u]*g[v]
剩下的问题就是f、g怎么求。
f必须从前面的递推过来,如果前面的没有递推完,那么就不能递推当前点,需要记录每个点可以从多少个点递推过来,这个一次dfs就可以完成。
g可以记忆化搜索来做,先把后继的全部递推完,再递推当前点,就是反过来递推。
程序:
#include <bits/stdc++.h> using namespace std; #define REP(i, a, b) for (int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define REP_EDGE(i, a) for (int i = (a); i != -1; i = e[i].nxt)
#define mset(a, b) memset(a, b, sizeof(a))
const int maxn = , maxm = , INF = 0x3fffffff, MOD = 1e9+;
typedef long long LL;
int n, m;
struct Edge
{
int u, v, w, nxt;
Edge (int u = , int v = , int w = , int nxt = ): u(u), v(v), w(w), nxt(nxt) {}
}e[maxm];
int head[maxn], label;
int dist[maxn], s_pre[maxn], f[maxn], g[maxn], ans[maxm];
bool vis[maxn];
queue <int> q; void ins(int u, int v, int w) { e[++label] = Edge(u, v, w, head[u]), head[u] = label; } void SPFA(int S)
{
REP(i, , n) dist[i] = INF, vis[i] = false;
vis[S] = true, dist[S] = , q.push(S);
while (!q.empty())
{
int u = q.front();
vis[u] = false, q.pop();
REP_EDGE(i, head[u])
{
int v = e[i].v, w = e[i].w;
if (dist[v] > dist[u]+w)
{
dist[v] = dist[u]+w;
if (!vis[v])
vis[v] = true, q.push(v);
}
}
}
} void find_pre(int u)
{
REP_EDGE(i, head[u])
{
int v = e[i].v, w = e[i].w;
if (dist[v] == dist[u]+w)
{
s_pre[v] ++;
if (!vis[v]) vis[v] = true, find_pre(v);
}
}
} void find_f(int u)
{
REP_EDGE(i, head[u])
{
int v = e[i].v, w = e[i].w;
if (dist[v] == dist[u]+w)
{
f[v] = (f[v]+f[u])%MOD;
if (--s_pre[v] == ) find_f(v);
}
}
} void find_g(int u)
{
g[u] = ;
REP_EDGE(i, head[u])
{
int v = e[i].v, w = e[i].w;
if (dist[v] == dist[u]+w)
{
if (!g[v]) find_g(v);
g[u] = (g[u]+g[v])%MOD;
}
}
} int main()
{
scanf("%d %d", &n, &m);
REP(i, , n) head[i] = -;
label = ;
REP(i, , m)
{
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
ins(u, v, w);
}
REP(i, , n)
{
SPFA(i);
mset(vis, ), mset(s_pre, ), mset(f, ), mset(g, );
vis[i] = true, find_pre(i);
f[i] = , find_f(i), find_g(i);
REP(j, , m)
if (dist[e[j].u]+e[j].w == dist[e[j].v])
ans[j] = (ans[j]+((LL)f[e[j].u]*g[e[j].v])%MOD)%MOD;
}
REP(i, , m) printf("%d\n", ans[i]);
return ;
}
BZOJ 2750 HAOI 2012 Road 高速公路 最短路的更多相关文章
- [HAOI 2012] Road
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2750 [算法] 考虑计算每个点对每条边的贡献 对于每个点首先运行SPFA或Dijks ...
- 【HAOI 2012】高速公路
Problem Description \(Y901\) 高速公路是一条重要的交通纽带,政府部门建设初期的投入以及使用期间的养护费用都不低,因此政府在这条高速公路上设立了许多收费站. \(Y901\) ...
- BZOJ 2749 HAOI 2012 外星人 数论 欧拉函数
题意: 给出一个数,给出的形式是其分解质因数后,对应的质因数pi及其次数qi,问对这个数不停求phi,直至这个数变成1,需要多少次.(多组数据) 范围:pi <= 1e5,qi <= 1e ...
- 大暴力——[HAOI]2012音量调节
题目:[HAOI]2012音量调节 描述: 问题描述 一个吉他手准备参加一场演出.他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都要改变一次音量.在演出开始之前,他已经做好了一个列表,里 ...
- [BZOJ 2299][HAOI 2011]向量 题解(裴蜀定理)
[BZOJ 2299][HAOI 2011]向量 Description 给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), ...
- [BZOJ 2301] [HAOI 2011] Problem b (莫比乌斯反演)(有证明)
[BZOJ 2301] [HAOI 2011] Problem b (莫比乌斯反演)(有证明) 题面 T组询问,每次给出a,b,c,d,k,求\(\sum _{i=a}^b\sum _{j=c}^d[ ...
- BZOJ 2750: [HAOI2012]Road( 最短路 )
对于每个点都跑最短路, 然后我们得到了个DAG, 在这DAG上更新每条边的答案. 考虑e(u, v)∈DAG对答案的贡献: 假设从S到u得路径数为A[u], 从v出发到达任意点的路径数为B[v], ...
- bzoj 2750: [HAOI2012]Road
Description C国有n座城市,城市之间通过m条单向道路连接.一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小.两条最短路不同,当且仅当它们包含的道路序列不同.我 ...
- HAOI 2012 高速公路
https://www.luogu.org/problem/show?pid=2221 题目描述 Y901高速公路是一条重要的交通纽带,政府部门建设初期的投入以及使用期间的养护费用都不低,因此政府在这 ...
随机推荐
- go 流程控制
if else 语句 基本语法 if condition { //do something } if condition { //do something } else if condition { ...
- [转载]Windows服务编写原理及探讨(3)
(三)对服务的深入讨论之下 现在我们还剩下一个函数可以在细节上讨论,那就是服务的CtrlHandler函数. 当调用RegisterServiceCtrlHandler函数时,SCM得到并保存这个回调 ...
- 创建自己的maven模板
概述 使用maven创建项目时,提供的基础的工程太简单不是想要的,并且创建过程很慢,使用起来体验不好.如果可以根据自己的需要,直接创建模板,然后进行类似项目拷贝的工作,那就完美.幸运的是,maven提 ...
- 洛谷P1242 新汉诺塔
传送门啦 首先要将第n个盘子从x到y,那么就要把比n小的盘子全部移到6-x-y,然后将n移到y 仔细想想:6代表的是3根初始柱,3根目标柱. 6-(x+y) 便是我们的中转柱了,因为到这个位置是最优的 ...
- Python学习1-Python和Pycharm的下载与安装
本文主要介绍Python的下载安装和Python编辑器Pycharm的下载与安装. 一.Python的下载与安装 1.下载 到Python官网上下载Python的安装文件,进入网站后显示如下图: 网速 ...
- Git简明教程二、开始进行版本管理
上一篇介绍了Git中的一些基本概念.本篇来实际看一看如何通过几个常用命令来快速上手Git,完成版本管理的日常操作(核心操作). 0. 准备工作 安装Git后,请先在你的电脑上新建或选择一个目录作为测试 ...
- 20165203《Java程序设计》第三周学习总结
教材学习内容总结 1.类: (1)类的声明:class+类名 (2)类体:成员变量的声明+方法(局部变量+语句) 注意: 方法体内声明的局部变量只在方法内有效和书写位置有关. 局部变量和成员变量同名: ...
- C语言-删除注释
C语言中的注释,不嵌套,一律使用/* */的形式.不过双引号中的/* */则不能算是注释. 以下是正确的代码 /* * ===================================== ...
- 《精通Python设计模式》学习结构型之MVC模式
这个就不需要多评论了, 哪个主流的PYTHON的WEB框架都有这些模式实现哈. quotes = ('A man is not complete until he is married. Then h ...
- chromiumFx编译使用
CEF chormeFx 为针对.Net的CEF框架,下载链接为: https://bitbucket.org/chromiumfx/chromiumfx 点击Download可以下载chromium ...