题意:

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

范围: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. required_new spring事务传播行为无效碰到的坑!

    在测试事务传播行为的时候,因为用了同一个service中的方法测试,所以不管怎么设置都无效了: 原因是aop动态代理只会拦截一次执行方法,第二个方法是照搬的,只要调用其他service中的事务方法,传 ...

  2. 缓存数据库-redis介绍

    一:Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的 ...

  3. 原生JS实现AJAX、JSONP及DOM加载完成事件

    一.JS原生Ajax ajax:一种请求数据的方式,不需要刷新整个页面:ajax的技术核心是 XMLHttpRequest 对象:ajax 请求过程:创建 XMLHttpRequest 对象.连接服务 ...

  4. ubuntu12.04安装ruby2.3

    为了搭建github-pages博客,而github-pages后端依赖于ruby,且对版本有严格要求,自己尝试了各种姿势升级ruby2.3无果,最终在查阅了各种资料之后找到一个可行方案. icebu ...

  5. Luogu P1566 【加等式】

    看到这道题,我们首先注意到“找出其所有的加等式的个数”,自然地考虑运用计数DP求出若干数相加的和的个数 考虑将每个元素排序后DP处理若干数相加的和的个数 用f[i]表示 对于一个数a[i],对于前i- ...

  6. Python练手之爬虫

    很久没更新博客了,最近自学Python,写个在百度上爬算法题题解的爬虫,第一次写爬虫..纯当练手 慢慢来.. #coding:utf-8 ''' Created on 2016年11月22日 @aut ...

  7. celery在Django中的集成使用

    继上回安装和使用Redis之后,看看如何在Django中使用Celery.Celery是Python开发分布式任务列队的处理库.可以异步分布式地异步处理任务,也可定时执行任务等等.通常我们可以在Dja ...

  8. 20155225 2016-2017-2《Java程序设计》课程总结

    20155225 2016-2017-2<Java程序设计>课程总结 每周作业链接汇总 预备作业1:新的开始 预备作业2:C语言学习回顾 预备作业3:Linux基础入门和虚拟机的安装 第一 ...

  9. ***四种参数传递的形式——URL,超链接,js,form表单

    什么时候用GET,  查,删 什么时候用POST,增,改  (特列:登陆用Post,因为不能让用户名和密码显示在URL上) 4种get传参方式 <html xmlns="http:// ...

  10. spring boot配置文件中 spring.mvc.static-path-pattern 配置项

    spring boot项目中的静态资源文件存放在static文件下面,当通过浏览器访问这些静态文件时,发现必须要添加static作为前缀才能访问,折腾了一番后发现,这个前缀跟 spring.mvc.s ...