题意:

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

范围: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. kworker内核工作队列详解

    工作队列是另一种将工作推后执行的形式,它可以把工作交给一个内核线程去执行,这个下半部是在进程上下文中执行的,因此,它可以重新调度还有睡眠.    区分使用软中断/tasklet还是工作队列比较简单,如 ...

  2. mariadb/mysql使用Navicat连接报错

    [问题1] 使用Navicat连接服务器的mariadb/mysql时报错 access denied for user root@192.168.xx.xx(using password:yes) ...

  3. MySQL权限操作:Grant、Revoke

    数据库操作: 创建数据库.创建表——CREATE 删除数据库.删除表——DROP 删除表内容——TRUNCATE.DELETE(后者效率低.一行一行地删除记录) 查询数据库.查询表——SELECT 插 ...

  4. Linux_僵尸进程、挂载、block块、inode号

    僵尸进程: 基本概念: 进程分为父进程和子进程 父进程一死 子进程都会死 杀死主进程的时候  子进程也会被杀死 僵尸进程:主进程被杀死了  但是子进程还活着    子进程不会占用cpu但还是会占着内存 ...

  5. 客户端使用less方法

    <link rel="stylesheet/less" type="text/css" href="/css/style.less"& ...

  6. angular可自定义的对话框,弹窗指令

    指令不明的,推荐 AngularJS指令参数详解 github地址 以下为示例代码 <!DOCTYPE html> <html lang="en" ng-app= ...

  7. HDU 2819 Swap(行列式性质+最大匹配)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2819 题目大意:给你一个n*n的01矩阵,问是否可以通过任意交换整行或者整列使得正对角线上都是1. ...

  8. (一)问候 Jsoup

    第一节: Jsoup 简介 Jsoup简介 jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQu ...

  9. 查找sqlserver数据库中,查询某值所表名和字段名

    有时候我们想通过一个值知道这个值来自数据库的哪个表以及哪个字段,通过一个存储过程实现的.只需要传入一个想要查找的值,即可查询出这个值所在的表和字段名. 前提是要将这个存储过程放在所查询的数据库. CR ...

  10. 34、疯狂java讲义第三版

    内容中包含 base64string 图片造成字符过多,拒绝显示