对于每个点都跑最短路, 然后我们得到了个DAG, 在这DAG上更新每条边的答案.

考虑e(u, v)∈DAG对答案的贡献:  假设从S到u得路径数为A[u], 从v出发到达任意点的路径数为B[v], 那么e(u, v)的答案可以加上A[u] * B[v](显然).

A可以按拓扑序递推得到, B可以通过记忆化搜索得到, 都是O(m). 所以总时间复杂度O(nmlogn + nm)

-------------------------------------------------------------------------------------

#include<bits/stdc++.h>
  
#define rep(i, n) for(int i = 0; i < n; i++)
#define clr(x, c) memset(x, c, sizeof(x))
#define REP(x) for(edge* e = head[x]; e; e = e->next)
#define foreach(e, x) for(__typeof(x.begin()); e != x.end(); e++)
#define mod(x) ((x) %= MOD)
 
using namespace std;
 
const int maxn = 1509, maxm = 5009;
const int MOD = 1000000007;
 
struct edge {
int to, w, num;
edge* next;
} E[maxm], *pt = E, *head[maxn];
 
inline void addedge(int u, int v, int d, int _) {
pt->to = v, pt->w = d, pt->num = _;
pt->next = head[u];
head[u] = pt++;
}
 
struct node {
int x, w;
bool operator < (const node &t) const {
return w > t.w;
}
};
 
int d[maxn], cnt[maxn], ans[maxm], A[maxn], B[maxn], n;
 
void dijkstra(int S) {
rep(i, n) d[i] = MOD;
d[S] = 0;
priority_queue<node> Q;
Q.push( (node) {S, 0} );
while(!Q.empty()) {
node t = Q.top(); Q.pop();
if(d[t.x] != t.w) continue;
REP(t.x) if(d[t.x] + e->w < d[e->to]) {
d[e->to] = d[t.x] + e->w;
Q.push( (node) {e->to, d[e->to]} );
}
}
}
 
// get B
int dp(int x) {
if(B[x]) return B[x];
REP(x) if(d[e->to] == d[x] + e->w)
   mod(B[x] += dp(e->to));
return ++B[x];
}
 
//get A
void DFS(int x) {
REP(x) if(d[e->to] == d[x] + e->w) {
mod(A[e->to] += A[x]);
if(!--cnt[e->to]) DFS(e->to);
}
}
 
void dfs(int x) {
REP(x) if(d[e->to] == d[x] + e->w)
if(!cnt[e->to]++) dfs(e->to);
}
 
void work(int x) {
dijkstra(x);
clr(cnt, 0), clr(A, 0), clr(B, 0);
dfs(x), dp(x), A[x] = 1, DFS(x);
rep(i, n)
   REP(i) if(d[i] + e->w == d[e->to])
       mod(ans[e->num] += 1LL * A[i] * B[e->to] % MOD);
}
 
inline int read() {
char c = getchar();
for(; !isdigit(c); c = getchar());
int ans = 0;
for(; isdigit(c); c = getchar())
   ans = ans * 10 + c - '0';
return ans;
}
 
int main() {
freopen("test.in", "r", stdin);
int m;
clr(head, 0), clr(ans, 0);
cin >> n >> m;
rep(i, m) {
int u = read() - 1, v = read() - 1, w = read();
addedge(u, v, w, i);
}
rep(i, n) work(i);
for(int* t = ans; t != ans + m; t++)
   printf("%d\n", *t);
return 0;
}

-------------------------------------------------------------------------------------

2750: [HAOI2012]Road

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 356  Solved: 163
[Submit][Status][Discuss]

Description

C国有n座城市,城市之间通过m条单向道路连接。一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小。两条最短路不同,当且仅当它们包含的道路序列不同。我们需要对每条道路的重要性进行评估,评估方式为计算有多少条不同的最短路经过该道路。现在,这个任务交给了你。

Input

第一行包含两个正整数n、m
接下来m行每行包含三个正整数u、v、w,表示有一条从u到v长度为w的道路

Output

输出应有m行,第i行包含一个数,代表经过第i条道路的最短路的数目对1000000007取模后的结果

Sample Input

4 4
1 2 5
2 3 5
3 4 5
1 4 8

Sample Output

2
3
2
1

HINT

数据规模

30%的数据满足:n≤15、m≤30

60%的数据满足:n≤300、m≤1000

100%的数据满足:n≤1500、m≤5000、w≤10000

Source

BZOJ 2750: [HAOI2012]Road( 最短路 )的更多相关文章

  1. bzoj 2750: [HAOI2012]Road

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

  2. bzoj 2750: [HAOI2012]Road【spfa+dfs】

    枚举起点做spfa,然后一条边在最短路上的条件是dis[e[i].to]==dis[u]+e[i].va,所以每次spfa完之后,dfs出a[i]表示经过i点的最短路的起点数,b[i]表示经过i点的最 ...

  3. BZOJ2750: [HAOI2012]Road

    2750: [HAOI2012]Road Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 261  Solved: 113[Submit][Status ...

  4. [HAOI2012]Road

    2750: [HAOI2012]Road Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 728  Solved: 349[Submit][Status ...

  5. BZOJ 2750 HAOI 2012 Road 高速公路 最短路

    题意: 给出一个有向图,求每条边有多少次作为最短路上的边(任意的起始点). 范围:n <= 1500, m <= 5005 分析: 一个比较容易想到的思路:以每个点作为起点,做一次SPFA ...

  6. BZOJ 2752: [HAOI2012]高速公路(road)( 线段树 )

    对于询问[L, R], 我们直接考虑每个p(L≤p≤R)的贡献,可以得到 然后化简一下得到 这样就可以很方便地用线段树, 维护一个p, p*vp, p*(p+1)*vp就可以了 ----------- ...

  7. BZOJ 3040: 最短路(road) ( 最短路 )

    本来想学一下配对堆的...结果学着学着就偏了... 之前 kpm 写过这道题 , 前面的边不理它都能 AC .. 我也懒得去写前面的加边了... 用 C++ pb_ds 库里的 pairing_hea ...

  8. BZOJ 2752: [HAOI2012]高速公路(road) [线段树 期望]

    2752: [HAOI2012]高速公路(road) Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1219  Solved: 446[Submit] ...

  9. Road(bzoj 2750)

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

随机推荐

  1. CentOS 6.5 PYPI本地源制作

    转载:blog.csdn.net/tantexian   一.安装pip2pi工具: pip install pip2pi 或 git clone https://github.com/wolever ...

  2. MYSql和PHP计算数据性能

    MYSQL不是有很多内部计算函数吗? 比如我要计算一列数据的平均值,,那我是直接用MYSQL里面的函数在SQL语句中计算 快 :还是用SQL把数据取出来了,用PHP计算快呢?(SQL语句PHP语句都用 ...

  3. 远程读取URL 建议用curl代替file_get_contents

    初学php的朋友们,很容易翻一个错误,在写采集程序或者调用api接口总会有线考虑到使用file_get_contents函数来或许内容,程序的访问量不大倒是没什么影响,但是访问量提升了那非常的悲剧了, ...

  4. 转: 模块化开发框架seajs简介

    JavaScript模块化开发库之SeaJSSeaJS由国内的牛人lifesinger开发.目前版本是1.1.1,源码不到1500行,压缩后才4k,质量极高.这篇会讲述SeaJS的一些基本用法,不会面 ...

  5. AOI自动光学检测机技术在电路板检查中的应用

    1.简述 AOI技术在许多不同的制造业领域使用,自从电子影像技术开始发展,就被各种人利用在不同的应用领域.大家最熟悉的数字相机.数字摄影机是大家生活中最常用到的器材之一,而工业产品的生产也大量使用这些 ...

  6. pod update --verbose --no-repo-update

    最近使用CocoaPods来添加第三方类库,无论是执行pod install还是pod update都卡在了Analyzing dependencies不动 原因在于当执行以上两个命令的时候会升级Co ...

  7. cocos2dx的runAction: 反复运行,多个动作连接运行,多个动作同一时候运行的实现

    cocos2dx的 runAction,假设某个动作重复运行用cc.RepeatForever:create, 多个动作连接运行用cc.Sequence:create,多个动作同一时候运行用cc.Sp ...

  8. 【剑指Offer学习】【面试题18 :树的子结构】

    题目:输入两棵二叉树A 和B.推断B 是不是A 的子结构. 二叉树结点的定义: /** * 二叉树的树结点 */ public static class BinaryTreeNode { int va ...

  9. SSH框架入门学习之二(spring)

    Spring也是一个开源框架,我在学习Spring的时候,认为最重要的几点是:IOC(控制反转).AOP(面向切面)和容器概念. 详细的教程还请大家去看网上的视频,这里贴一个小Demo以供学习. (前 ...

  10. Group DataList

    一,效果图. 二,源代码. <!DOCTYPE html><html><head> <meta charset="UTF-8"> & ...