[题目链接]

https://www.lydsy.com/JudgeOnline/problem.php?id=2750

[算法]

考虑计算每个点对每条边的贡献

对于每个点首先运行SPFA或Dijkstra单源最短路 , 建出以该点为根的最短路树(图)

由于最短路图是一个DAG(有向无环图) , 我们可以求出其拓扑序列 , 对于每个点i , 计算 :

CNT1 : 从枚举的点到该点的 , 最短路图上的路径条数

CNT2 : 从该点出发 , 在最短路图上 , 有多少条路径

对于每条在最短路图上的边 , 用乘法原理计算贡献即可

时间复杂度 : O(NM)

[代码]

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int N = ;
const int inf = 2e9;
const int P = 1e9 + ; struct edge
{
int to , w , nxt;
} e[N << ]; int n , m , tot;
int dist[N] , cnta[N] , cntb[N] , u[N] , v[N] , w[N] , head[N] , topo[N] , ans[N];
bool ok[N]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline void addedge(int u , int v , int w)
{
++tot;
e[tot] = (edge){v , w , head[u]};
head[u] = tot;
}
inline void spfa(int S)
{
static bool inq[N];
queue< int > q;
for (int i = ; i <= n; ++i)
{
dist[i] = inf;
inq[i] = false;
cnta[i] = cntb[i] = ;
}
for (int i = ; i <= m; ++i) ok[i] = false;
q.push(S);
inq[S] = true;
dist[S] = ;
while (!q.empty())
{
int cur = q.front();
q.pop();
inq[cur] = false;
for (int i = head[cur]; i; i = e[i].nxt)
{
int v = e[i].to , w = e[i].w;
if (dist[cur] + w < dist[v])
{
dist[v] = dist[cur] + w;
if (!inq[v])
{
inq[v] = true;
q.push(v);
}
}
}
}
for (int i = ; i <= m; ++i)
if (dist[u[i]] + w[i] == dist[v[i]]) ok[i] = true;
}
inline void calc()
{
queue< int > q;
static int deg[N];
for (int i = ; i <= n; ++i)
deg[i] = ;
for (int i = ; i <= m; ++i)
if (ok[i]) ++deg[v[i]];
for (int i = ; i <= n; i++)
if (!deg[i])
{
cnta[i] = ;
q.push(i);
}
int M = ;
while (!q.empty())
{
int cur = q.front();
q.pop();
topo[++M] = cur;
for (int i = head[cur]; i; i = e[i].nxt)
{
int v = e[i].to;
if (!ok[i]) continue;
cnta[v] = (cnta[v] + cnta[cur]) % P;
if (!(--deg[v])) q.push(v);
}
}
for (int i = n; i >= ; i--)
{
++cntb[topo[i]];
for (int j = head[topo[i]]; j; j = e[j].nxt)
{
int v = e[j].to;
if (!ok[j]) continue;
cntb[topo[i]] = (cntb[topo[i]] + cntb[v]) % P;
}
}
}
inline void update(int S)
{
spfa(S);
calc();
for (int i = ; i <= m; ++i)
if (ok[i]) ans[i] = (ans[i] + 1ll * cnta[u[i]] * cntb[v[i]] % P) % P;
} int main()
{ read(n); read(m);
for (int i = ; i <= m; ++i)
{
read(u[i]); read(v[i]); read(w[i]);
addedge(u[i] , v[i] , w[i]);
}
for (int i = ; i <= n; ++i) update(i);
for (int i = ; i <= m; ++i) printf("%d\n" , ans[i]); return ; }

[HAOI 2012] Road的更多相关文章

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

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

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

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

  3. HAOI 2012 高速公路

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

  4. [HAOI 2012]音量调节

    Description 一个吉他手准备参加一场演出.他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都要改变一次音量.在演出开始之前,他已经做好了一个列表,里面写着在每首歌开始之前他想要改 ...

  5. 【HAOI 2012】高速公路

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

  6. 解题:HAOI 2012 道路

    题面 这题不开O2怎么过=.= 可能这种有关最短路的计数题做多了就有些感觉了...... 以每个点为基准跑出一张最短路图,然后对每个边$(u,v)$统计两个东西.一个$pre[u]$表示到达$u$这个 ...

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

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

  8. [HAOI 2012] 容易题

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2751 [算法] 考虑k = 0的情况 , 根据乘法原理 : Ans = (n * ( ...

  9. [HAOI 2012] 外星人

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2749 [算法] 首先 , 每次对一个数x进行操作 , 只会使该数减少一个2的因子 那 ...

随机推荐

  1. SVN服务器配置说明 【转】

    http://www.cnblogs.com/ricksun/articles/1564905.html 1.前 言 花了72小时,终于把 Subversion 初步掌握了.从一个连“什么是版本控制” ...

  2. 算法之美--3.2.2 MP算法

    这块硬骨头,放在这里半年的时间了,一直没有动,今天周末看看,书上把过程写的比较详细,自己基本也看懂了,但是对代码本身的编写还是比较生疏,要经常复习,估计才能看透,后面有看了kmp;这两者之间的关系也是 ...

  3. JavaSE入门学习6:Java基础语法之运算符和语句(上)

    继续接着上篇:JavaSE入门学习5:Java基础语法(一)来看Java的基础语法. 五运算符 运算符是一种"功能"符号,用以通知Java进行相关的运算.比方.我们须要将变量age ...

  4. HeadFirst设计模式 之 C++实现(三):Decorator(装饰者模式)

    装饰者模式是非常有意思的一种设计模式,你将可以在不改动不论什么底层代码的情况下.给你的(或别人的)对象赋予新的职责. 不是使用继承每回在编译时超类上改动代码,而是利用组合(composition)和托 ...

  5. angular - 安装 -1

    在阅读以下教程以前,请安装node,请先确保您的使用平台:Win.Mac.Linux 首次安装node以后,我们先检测版本 node -v npm -v 这样就代表安装成功,那么我们可以进入下一步了 ...

  6. JAVA Timer定时器使用方法

    JAVA  Timer 定时器测试 MyTask.java:package com.timer; import java.text.SimpleDateFormat;import java.util. ...

  7. java开始到熟悉105-107

    1,HashMap基本用法 package list; import java.util.HashMap; import java.util.Map; /** * 测试map的基本用法 * @auth ...

  8. UVA10317- Equating Equations(回溯+剪枝)

    题目链接 题意:给出一个式子,但这个式子不一定是等式,在'+','-','='符号位置不变的情况下,又一次排列数字的位置,使其成为等式.假设能够的话.输出当中一种排列方式. 思路:我们将等号右边的数所 ...

  9. selector模块使用

    #服务端 from socket import * import selectors sel=selectors.DefaultSelector() def accept(server_fileobj ...

  10. iOS移动开发周报-第19期

    iOS移动开发周报-第19期 前言 欢迎国内的iOS同行或技术作者向我提交周报线索,线索可以是新闻.教程.开发工具或开源项目,将相关文章的简介和链接在微博上发布并 @唐巧_boy 即可. [摘要]:本 ...