题意:

给出一个有向图,求每条边有多少次作为最短路上的边(任意的起始点)。

范围: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 高速公路 最短路的更多相关文章

  1. [HAOI 2012] Road

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2750 [算法] 考虑计算每个点对每条边的贡献 对于每个点首先运行SPFA或Dijks ...

  2. 【HAOI 2012】高速公路

    Problem Description \(Y901\) 高速公路是一条重要的交通纽带,政府部门建设初期的投入以及使用期间的养护费用都不低,因此政府在这条高速公路上设立了许多收费站. \(Y901\) ...

  3. BZOJ 2749 HAOI 2012 外星人 数论 欧拉函数

    题意: 给出一个数,给出的形式是其分解质因数后,对应的质因数pi及其次数qi,问对这个数不停求phi,直至这个数变成1,需要多少次.(多组数据) 范围:pi <= 1e5,qi <= 1e ...

  4. 大暴力——[HAOI]2012音量调节

    题目:[HAOI]2012音量调节 描述: 问题描述 一个吉他手准备参加一场演出.他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都要改变一次音量.在演出开始之前,他已经做好了一个列表,里 ...

  5. [BZOJ 2299][HAOI 2011]向量 题解(裴蜀定理)

    [BZOJ 2299][HAOI 2011]向量 Description 给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), ...

  6. [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[ ...

  7. BZOJ 2750: [HAOI2012]Road( 最短路 )

    对于每个点都跑最短路, 然后我们得到了个DAG, 在这DAG上更新每条边的答案. 考虑e(u, v)∈DAG对答案的贡献:  假设从S到u得路径数为A[u], 从v出发到达任意点的路径数为B[v], ...

  8. bzoj 2750: [HAOI2012]Road

    Description C国有n座城市,城市之间通过m条单向道路连接.一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小.两条最短路不同,当且仅当它们包含的道路序列不同.我 ...

  9. HAOI 2012 高速公路

    https://www.luogu.org/problem/show?pid=2221 题目描述 Y901高速公路是一条重要的交通纽带,政府部门建设初期的投入以及使用期间的养护费用都不低,因此政府在这 ...

随机推荐

  1. oracle 创建表空间 、用户 、赋权、建表

    一.创建表空间 1.创建临时表空间 create temporary tablespace TS_TEM_TAB_SPACE tempfile 'D:\oracle\TS_TEM_TAB_SPACE. ...

  2. python3 asyncio官方文档中文版

    事件循环基类 事件循环基类 事件循环是由asyncio提供的核心执行装置.它提供了多种服务,包括: 注册.执行和关闭延时调用(超时) 为各种通信创建客户端和服务端传输 为一个外部程序通信启动子进程和相 ...

  3. OpenStack Benchmark - Rally

    作为以基于OpenStack的云平台的基准测试工具 -- Rally, 其功能不仅是测试云的性能&&稳定性, 还可以安装OpenStack,以及以良好的表现形式(web 页面)展现测试 ...

  4. java基础30 List集合下的LinkedList集合

    单例集合体系: ---------| collection  单例集合的根接口--------------| List  如果实现了list接口的集合类,具备的特点:有序,可重复       注:集合 ...

  5. P1183 多边形的面积

    一道睡论数论题 其实是AC300祭才做的水题 题意: 很直白的的题意啊,就是求任意一个多边形的面积 所以我们来安利一下一个求多边形面积的数学通式: 给定多边形的顶点坐标(有序),让你来求这个多边形的面 ...

  6. delphi TComponent类 2

    来自:http://blog.csdn.net/lailai186/article/details/7442385 ------------------------------------------ ...

  7. yum安装Mysql-5.6

    MySQL yum库提供了一个简单的和方便的方法来安装和更新MySQL相关的软件包到最新版本. MySQL yum库文档说明:http://dev.mysql.com/doc/mysql-yum-re ...

  8. python 常用的标准库及第三方库

    标准库Python拥有一个强大的标准库.Python语言的核心只包含数字.字符串.列表.字典.文件等常见类型和函数,而由Python标准库提供了系统管理.网络通信.文本处理.数据库接口.图形系统.XM ...

  9. 面试题:输入两个整数 n 和 m,从数列1,2,3…….n 中 随意取几个数, 使其和等于 m

    问题: 2010年中兴面试题 编程求解: 输入两个整数 n 和 m,从数列1,2,3…….n 中 随意取几个数, 使其和等于 m ,要求将其中所有的可能组合列出来. 思路: 类似这种组合问题一般都是使 ...

  10. 关于RundownProtect到底是什么东西

    RundownProtect这个字段相信只要是读过WRK源码的都会看过这个东西,这个字段在进程和线程的结构中都存在.最典型的例子就是对进程要进行什么操作的时候会先引用这个字段进行加保护,等操作结束后再 ...